打算为入门ARM指令集写点初级文章,没什么远大理想,纯当娱乐算了。
首先编辑一个最简单的函数:
#include <stdio.h> void main() { int d = 4; }
然后编译:arm-linux-gnueabihf-gcc test.c -o test1
然后看看汇编代码:arm-linux-gnueabihf-objdump -D test1;每一句的含义我已经给出详细注释
0000835c <main>:
835c: b480 push {r7}
;程序用到了r7寄存器,所以需要保护以免破坏之前的数据
835e: b083 sub sp, #12
;堆栈向下增长栈用的不多,只需要12个字节就够用了: int d需要4个,main的参数需要8个
8360: af00 add r7, sp, #0
;因为堆栈寄存器sp不能用作寄存器寻址,所以没办法,只好用r7 = sp + 0这种笨办法
8362: f04f 0304 mov.w r3, #4
;参与int d = 4这条语句的是r3,这是通用寄存器,spec定义大家都可以用,不需要保护
8366: 607b str r3, [r7, #4]
; 把4存储到sp+4所指定的栈里,c语言描述:*(sp + 4) = 4
8368: f107 070c add.w r7, r7, #12
;还记得第二条:sub sp, #12吗?此句和下一句是为从堆栈里恢复原来的r7--pop {r7},做准备;
836c: 46bd mov sp, r7 ;r7已经是原来的sp了
836e: bc80 pop {r7} ;弹出sp指向的内存数据给r7,c语言:r7 = *sp;
8370: 4770 bx lr ; 跳转到lr地址--进入main函数的下一条地址
8372: bf00 nop
我们再编辑一个稍微复杂一点点函数:
#include <stdio.h> void main() { int a = 1; char b = 2; short c = 3; int d = 4; int e; e = b; printf("%d\n", e); e = a; printf("%d\n", e); e = c; printf("%d\n", e); e = d; printf("%d\n", e); }
然后看看汇编代码:
00008394 <main>: 8394: b580 push {r7, lr} 8396: b084 sub sp, #16 8398: af00 add r7, sp, #0 839a: f04f 0301 mov.w r3, #1 839e: 603b str r3, [r7, #0] 83a0: f04f 0302 mov.w r3, #2 83a4: 73fb strb r3, [r7, #15] 83a6: f04f 0303 mov.w r3, #3 83aa: 81bb strh r3, [r7, #12] 83ac: f04f 0304 mov.w r3, #4 83b0: 607b str r3, [r7, #4] 83b2: 7bfb ldrb r3, [r7, #15] 83b4: 60bb str r3, [r7, #8] 83b6: f248 4360 movw r3, #33888 ; 0x8460 83ba: f2c0 0300 movt r3, #0 83be: 4618 mov r0, r3 83c0: 68b9 ldr r1, [r7, #8] 83c2: f7ff ef92 blx 82e8 <_init+0x20> 83c6: 683b ldr r3, [r7, #0] 83c8: 60bb str r3, [r7, #8] 83ca: f248 4360 movw r3, #33888 ; 0x8460 83ce: f2c0 0300 movt r3, #0 83d2: 4618 mov r0, r3 83d4: 68b9 ldr r1, [r7, #8] 83d6: f7ff ef88 blx 82e8 <_init+0x20> 83da: f9b7 300c ldrsh.w r3, [r7, #12] 83de: 60bb str r3, [r7, #8] 83e0: f248 4360 movw r3, #33888 ; 0x8460 83e4: f2c0 0300 movt r3, #0 83e8: 4618 mov r0, r3 83ea: 68b9 ldr r1, [r7, #8] 83ec: f7ff ef7c blx 82e8 <_init+0x20> 83f0: 687b ldr r3, [r7, #4] 83f2: 60bb str r3, [r7, #8] 83f4: f248 4360 movw r3, #33888 ; 0x8460 83f8: f2c0 0300 movt r3, #0 83fc: 4618 mov r0, r3 83fe: 68b9 ldr r1, [r7, #8] 8400: f7ff ef72 blx 82e8 <_init+0x20> 8404: f107 0710 add.w r7, r7, #16 8408: 46bd mov sp, r7 840a: bd80 pop {r7, pc}