0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C言語ローカル変数のメモリ配置をx86とARMで観察する

Last updated at Posted at 2025-10-22

目的

リトルエンディアンのメモリの並びを見る。
x86とARMでメモリの配置を比べます。
ずっとARMはビックエンディアンしかないと思い込んでおり、x86とARMで逆になっているという記事を書きたかったのですが、ARM両方で動作できるみたいで、筆者の使っているARM小型サーバではリトルエンディアンとなっていたのでビックエンディアンの検証はできませんでした。

前回以下の記事を書きましたが、内容的にはこれらを合わせて、構成を見直して読みやすくしただけです。
ARM32上でC言語のローカル変数がスタックにどう配置されるかを観察する
Cのローカル変数はメモリ上でどう配置されるか? – x86-64 スタックと RBP オフセットの観察

C言語

test.c
void func(){
  volatile int a = 0x12345678;
  volatile char b = 0xAB;
}

int main(){
  func();
  return 0;
}

x86

逆アセンブルして各命令のアドレスを調べる。

gcc -no-pie -gstabs -O0 test.c -o test
objdump -d -M intel test
0000000000401106 <func>:
  401106:	f3 0f 1e fa          	endbr64 
  40110a:	55                   	push   rbp
  40110b:	48 89 e5             	mov    rbp,rsp
  40110e:	c7 45 fc 78 56 34 12 	mov    DWORD PTR [rbp-0x4],0x12345678
  401115:	c6 45 fb ab          	mov    BYTE PTR [rbp-0x5],0xab
  401119:	90                   	nop
  40111a:	5d                   	pop    rbp
  40111b:	c3                   	ret  

nop命令で実行を止めてメモリの配置を確認する

gdb test
break *0x401119 # nopにブレイクポイントを置く
run # nopを実行する直前まで動かす。
info registers rbp # rbpの値を確認する
x/8xb $rbp-0x8

実際に値を確認

test@test-ThinkPad-X280:~/test$ gdb test
(gdb) break *0x401119
Breakpoint 1 at 0x401119: file test.c, line 4.
(gdb) run
Starting program: /home/test/test/test 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, func () at test.c:4
4	}
(gdb) info registers rbp
rbp            0x7fffffffdfd0      0x7fffffffdfd0
(gdb) x/8xb $rbp-0x8
0x7fffffffdfc8:	0x64	0x00	0x00	0xab	0x78	0x56	0x34	0x12

メモリの分布は以下の様になっている。

0x7fffffffdfc8:  0x64
0x7fffffffdfc9:  0x00
0x7fffffffdfca:  0x00
0x7fffffffdfcb:  0xab
0x7fffffffdfcc:  0x78 ← 変数a終了
0x7fffffffdfcd:  0x56
0x7fffffffdfce:  0x34
0x7fffffffdfcf:  0x12 ← 変数a開始

ARM32

実験に使うLinux小型サーバがリトルエンディアンかビットエンディアンか調べる。

testuser@CasaOS:~/test$ lscpu | grep Endian
Byte Order:                      Little Endian

逆アセンブルして各命令のアドレスを調べる。

gcc -no-pie -g -O0 test.c -o test
objdump -d test

実際に値を確認

000103c0 <func>:
   103c0:	b480      	push	{r7}
   103c2:	b083      	sub	sp, #12
   103c4:	af00      	add	r7, sp, #0
   103c6:	f245 6378 	movw	r3, #22136	@ 0x5678
   103ca:	f2c1 2334 	movt	r3, #4660	@ 0x1234
   103ce:	607b      	str	r3, [r7, #4]
   103d0:	23ab      	movs	r3, #171	@ 0xab
   103d2:	70fb      	strb	r3, [r7, #3]
   103d4:	bf00      	nop
   103d6:	370c      	adds	r7, #12
   103d8:	46bd      	mov	sp, r7
   103da:	f85d 7b04 	ldr.w	r7, [sp], #4
   103de:	4770      	bx	lr

nop命令で実行を止めてメモリの配置を確認する

gdb ./test
break *0x103d4
run
info registers r7
x/8xb $r7
testuser@CasaOS:~/test$ gdb ./test
(gdb) break *0x103d4
Breakpoint 1 at 0x103d4: file test.c, line 4.
(gdb) run
Starting program: /home/testuser/test/test 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".

Breakpoint 1, func () at test.c:4
4	}
(gdb) info registers r7
r7             0xbefff3d8          3204445144
(gdb) x/8xb $r7
0xbefff3d8:	0x90	0x41	0xec	0xab	0x78	0x56	0x34	0x12

メモリの分布は以下の様になっている。

0xbefff3d8:  0x90
0xbefff3d9:  0x41
0xbefff3da:  0xec
0xbefff3db:  0xab
0xbefff3dc:  0x78 ← 変数a終了
0xbefff3dd:  0x56
0xbefff3de:  0x34
0xbefff3df:  0x12 ← 変数a開始

リトルエンディアンなのでx86と同じく高アドレスに上位ビット、低アドレスに下位ビットの順番で並んでいる。

動作環境(Linux / x86_64 版)

OS: Ubuntu 22.04.5 LTS (Jammy Jellyfish)
Kernel: Linux 6.8.0-84-generic
CPU: Intel Core i5-8250U, 4 cores, 8 threads, Little Endian
Architecture: x86_64

動作環境(Linux / ARM 版)

OS: Armbian 23.08.0-trunk (Debian 12 Bookworm)
Kernel: Linux 6.1.38-meson (armv7l)
CPU: ARM Cortex-A5, 4 cores, Little Endian
Architecture: armv7l
備考: UbuntuからSSH接続して使用

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?