arm汇编文件编译以及代码查看

汇编文件一般为.S结尾(S大写,小写的s一般不会有预处理的过程和语句。大写的S一般有预处理等等)


首先编写一个main.S

main:
mov r0,#1
mov r1,#2
ldr r2,add_func_l
bl r2
die:
b die
add_func:
add r0,r0,r1
bx lr
.align 4
add_func_l:.word add_func


执行一个r0=r0+r1的操作。随后死循环


对这个文件执行编译

./arm-linux-gnueabihf-as -o main.o main.S

产生了.o文件


查看反汇编代码

./arm-linux-gnueabihf-objdump -d main.o


得到如下结果

main.o:     file format elf32-littlearm




Disassembly of section .text:


00000000 <main>:
   0: e3a00001 mov r0, #1
   4: e3a01002 mov r1, #2
   8: e59f2010 ldr r2, [pc, #16] ; 20 <add_func_l>
   c: ebfffffe bl 0 <r2>


00000010 <die>:
  10: eafffffe b 10 <die>


00000014 <add_func>:
  14: e0800001 add r0, r0, r1
  18: e12fff1e bx lr
  1c: e1a00000 nop ; (mov r0, r0)


00000020 <add_func_l>:
  20: 00000014 .word 0x00000014
  24: e1a00000 nop ; (mov r0, r0)
  28: e1a00000 nop ; (mov r0, r0)
  2c: e1a00000 nop ; (mov r0, r0)


看ldr r2,[pc,#16]这一句,将PC+16地址里面的值赋值给了r2。

随后bl r2就是跳转到r2这里执行。

计算过程如下。

由于arm采用流水式的执行方式,读取-解析-执行,这个是执行的流水线。PC永远比正在执行的语句快两条指令。

1

执行=NULL

解析=NULL

PC= mov r0, #1

2

执行=NULL

解析= mov r0, #1

PC=mov  r1, #2

3

执行= mov r0, #1

解析=mov  r1, #2

PC=ldr r2, [pc, #16]


4

执行= mov  r1, #2

解析=ldr r2, [pc, #16]

PC=bl 0 <r2>


5

执行= ldr r2, [pc, #16]

解析=bl 0 <r2>

PC=b 10 <die>


这里开始执行 ldr r2,[PC,#16]

此时的PC指向b die也就是0x10的位置。所以 r2=[0x10+16]=[32]=[0x20]。此时0x20里面的值是0x14。因此r2=0x14

6

执行=bl 0 <r2>

解析=b 10 <die>

PC=add r0, r0, r1

执行bl的时候 会将PC-4放到lr里面。也就是b die的地址。同时流水线被清空。 PC也变化了


执行完整个函数

接下来执行b die 进入死循环








没有更多推荐了,返回首页