文章目录
- ARM 链接过程分析
- 源文件
- global_bss_file.c
- global_data_fle.c
- global_function_file.c
- global_rodata_file.c
- main.c
- 链接文件 link.lds
- 编译命令及反汇编命令
- 解析 .o 文件
- global_bss_file.o
- global_data_fle.o
- global_function_file.o
- global_rodata_file.o
- main.o
- 链接
- 观察链接前后的差异
- 地址变化
- main.o
ARM 链接过程分析
源文件
这里新建五个文件
- global_bss_file.c:定义了两个未初始化的全局变量
- global_bss_file.c:定义了两个初始化的全局变量
- global_function_file.c:定义了一个函数,函数实现传入的两个参数相加功能
- global_rodata_file.c:定义了两个只读常量,并初始化
- main.c:使用上述定义的变量和函数
根据上述自定义的链接脚本将这五个. c 文件链接为一个输出文件。编译环境为 arm-none-linux-gnueabihf-
global_bss_file.c
int bss_data1;
int bss_data2;
global_data_fle.c
int test_data1 = 1;
int test_data2 = 2;
global_function_file.c
int test_func(int a, int b)
{return a + b;
}
global_rodata_file.c
const int rodata_1 = 3;
const int rodata_2 = 4;
main.c
/* rodata */
extern const int rodata_1;
extern const int rodata_2;/* data */
extern int test_data1;
extern int test_data2;/* bss data(no init) */
extern int bss_data1;
extern int bss_data2;/* code */
extern int test_func(int a, int b);int main (int argc, int *argv[])
{bss_data1 = test_func(test_data1, test_data2);bss_data2 = test_func(rodata_1, rodata_2);return 0;
}
链接文件 link.lds
SECTIONS
{. = 0x00900000;.text :{*(.text)}.rodata :{*(.rodata)}. = 0x80000000;.data :{*(.data)}.bss :{*(.bss)}
}
编译命令及反汇编命令
命令示例
arm-none-linux-gnueabihf-gcc -c global_bss_file.c
arm-none-linux-gnueabihf-objdump -h global_bss_file.o > global_bss_file.sec
arm-none-linux-gnueabihf-objdump -s -d global_bss_file.o > global_bss_file.info
使用上述命令编译源文件之后会生成 global_bss_file.o/sec/info
,global_data_fle.o/sec/info
, global_function_file.o/sec/info
,global_rodata_file.o/sec/info
, 和 main.o/sec/info
等文件。
解析 .o 文件
global_bss_file.o
命令
arm-none-linux-gnueabihf-objdump -h global_bss_file.o >global_bss_file.sec
section,以及对应的 VMA 和 LMA
global_bss_file.o: file format elf32-littlearmSections:
Idx Name Size VMA LMA File off Algn0 .text 00000000 00000000 00000000 00000034 2**0CONTENTS, ALLOC, LOAD, READONLY, CODE1 .data 00000000 00000000 00000000 00000034 2**0CONTENTS, ALLOC, LOAD, DATA2 .bss 00000008 00000000 00000000 00000034 2**2ALLOC3 .comment 0000005e 00000000 00000000 00000034 2**0CONTENTS, READONLY4 .note.GNU-stack 00000000 00000000 00000000 00000092 2**0CONTENTS, READONLY5 .ARM.attributes 00000035 00000000 00000000 00000092 2**0CONTENTS, READONLY
global_bss_file.o 有六个 sections 分别是
- .text:代码段,没有包含任何有用的代码信息,所以 .text 段为 0
- .data:数据段,没有已经初始化的数据,所以 .data 段是 0
- .bss:未初始化变量段 8,源码总定义了两个 int 数据,所以 .bss 段的长度为 8
- .comment:存放一些 GNU 的通用信息
- .note.GNU-stack:GNU 的注释信息
- .ARM.attributes:编译器相关信息
使用下面命令查看详细信息
arm-none-linux-gnueabihf-objdump -s -d global_bss_file.o >global_bss_file.info
命令返回结果如下
global_bss_file.o: file format elf32-littlearmContents of section .comment:0000 00474343 3a202847 4e552054 6f6f6c63 .GCC: (GNU Toolc0010 6861696e 20666f72 20746865 20412d70 hain for the A-p0020 726f6669 6c652041 72636869 74656374 rofile Architect0030 75726520 31302e33 2d323032 312e3037 ure 10.3-2021.070040 20286172 6d2d3130 2e323929 29203130 (arm-10.29)) 100050 2e332e31 20323032 31303632 3100 .3.1 20210621.
Contents of section .ARM.attributes:0000 41340000 00616561 62690001 2a000000 A4...aeabi..*...0010 05372d41 00060a07 41080109 020a030c .7-A....A.......0020 01120414 01150117 03180119 011a021c ................0030 011e0622 01 ...".
- 由于还未链接,没有 .bss 段的相关信息
global_data_fle.o
命令
arm-none-linux-gnueabihf-objdump -h global_data_fle.o >global_data_fle.sec
section,以及对应的 VMA 和 LMA
global_data_fle.o: file format elf32-littlearmSections:
Idx Name Size VMA LMA File off Algn0 .text 00000000 00000000 00000000 00000034 2**0CONTENTS, ALLOC, LOAD, READONLY, CODE1 .data 00000008 00000000 00000000 00000034 2**2CONTENTS, ALLOC, LOAD, DATA2 .bss 00000000 00000000 00000000 0000003c 2**0ALLOC3 .comment 0000005e 00000000 00000000 0000003c 2**0CONTENTS, READONLY4 .note.GNU-stack 00000000 00000000 00000000 0000009a 2**0CONTENTS, READONLY5 .ARM.attributes 00000035 00000000 00000000 0000009a 2**0CONTENTS, READONLY
global_data_fle.o 同样有六个 sections 分别是
- .text:代码段,没有包含任何有用的代码信息,所以 .text 段为 0
- .data:数据段长度为 8,定义了两个 int 型全局变量并初始化,int 的长度是 4 个字节,两个 int 于是占用了 8 个字节,所以 .data 段的长度为 8
- .bss:没有未初始化的变量,所以 .bss 段为 0
- .comment:存放一些 GNU 的通用信息
- .note.GNU-stack:GNU 的注释信息
- .ARM.attributes:编译器相关信息
使用下面命令查看详细信息
arm-none-linux-gnueabihf-objdump -s -d global_data_fle.o >global_data_fle.info
命令结果如下
global_data_fle.o: file format elf32-littlearmContents of section .data:0000 01000000 02000000 ........
Contents of section .comment:0000 00474343 3a202847 4e552054 6f6f6c63 .GCC: (GNU Toolc0010 6861696e 20666f72 20746865 20412d70 hain for the A-p0020 726f6669 6c652041 72636869 74656374 rofile Architect0030 75726520 31302e33 2d323032 312e3037 ure 10.3-2021.070040 20286172 6d2d3130 2e323929 29203130 (arm-10.29)) 100050 2e332e31 20323032 31303632 3100 .3.1 20210621.
Contents of section .ARM.attributes:0000 41340000 00616561 62690001 2a000000 A4...aeabi..*...0010 05372d41 00060a07 41080109 020a030c .7-A....A.......0020 01120414 01150117 03180119 011a021c ................0030 011e0622 01 ...".
-
由于还未链接,所以 .data 段的数据起始地址为
0
-
data.o 里面只有 .data 段的数据,并且长度为 8 个字节,小端模式,的确包含了 01000000 以及 02000000 两个全局变量的数据。
global_function_file.o
命令
arm-none-linux-gnueabihf-objdump -h global_function_file.o >global_function_file.sec
section,以及对应的 VMA 和 LMA
global_function_file.o: file format elf32-littlearmSections:
Idx Name Size VMA LMA File off Algn0 .text 0000001c 00000000 00000000 00000034 2**1CONTENTS, ALLOC, LOAD, READONLY, CODE1 .data 00000000 00000000 00000000 00000050 2**0CONTENTS, ALLOC, LOAD, DATA2 .bss 00000000 00000000 00000000 00000050 2**0ALLOC3 .comment 0000005e 00000000 00000000 00000050 2**0CONTENTS, READONLY4 .note.GNU-stack 00000000 00000000 00000000 000000ae 2**0CONTENTS, READONLY5 .ARM.attributes 00000035 00000000 00000000 000000ae 2**0CONTENTS, READONLY
global_function_file.o 同样有六个 sections 分别是
- .text:代码段,文件中定义了一个函数,所以 .text 的数据长度不为 0
- .data:数据段,未定义任何数据,所以为 .data 段的长度为 0
- .bss:没有未初始化的变量,所以 .bss 段的长度为 0
- .comment:存放一些 GNU 的通用信息
- .note.GNU-stack:GNU 的注释信息
- .ARM.attributes:编译器相关信息
使用下面命令查看详细信息
arm-none-linux-gnueabihf-objdump -s -d global_function_file.o >global_function_file.info
命令结果如下
global_function_file.o: file format elf32-littlearmContents of section .text:0000 80b483b0 00af7860 39607a68 3b681344 ......x`9`zh;h.D0010 18460c37 bd465df8 047b7047 .F.7.F]..{pG
Contents of section .comment:0000 00474343 3a202847 4e552054 6f6f6c63 .GCC: (GNU Toolc0010 6861696e 20666f72 20746865 20412d70 hain for the A-p0020 726f6669 6c652041 72636869 74656374 rofile Architect0030 75726520 31302e33 2d323032 312e3037 ure 10.3-2021.070040 20286172 6d2d3130 2e323929 29203130 (arm-10.29)) 100050 2e332e31 20323032 31303632 3100 .3.1 20210621.
Contents of section .ARM.attributes:0000 41340000 00616561 62690001 2a000000 A4...aeabi..*...0010 05372d41 00060a07 41080109 020a030c .7-A....A.......0020 01120414 01150117 03180119 011a021c ................0030 011e0622 01 ...".Disassembly of section .text:00000000 <test_func>:0: b480 push {r7}2: b083 sub sp, #124: af00 add r7, sp, #06: 6078 str r0, [r7, #4]8: 6039 str r1, [r7, #0]a: 687a ldr r2, [r7, #4]c: 683b ldr r3, [r7, #0]e: 4413 add r3, r210: 4618 mov r0, r312: 370c adds r7, #1214: 46bd mov sp, r716: f85d 7b04 ldr.w r7, [sp], #41a: 4770 bx lr
-
由于还未链接,所以代码段 .text 的起始地址为
0
-
global_function_file.o 里面只有 .text 段的数据,其代码实现数据相加功能。
global_rodata_file.o
objdump 解析命令
arm-none-linux-gnueabihf-objdump -h global_rodata_file.o >global_rodata_file.sec
objdump 解析结果:section,以及对应的 VMA 和 LMA
global_rodata_file.o: file format elf32-littlearmSections:
Idx Name Size VMA LMA File off Algn0 .text 00000000 00000000 00000000 00000034 2**0CONTENTS, ALLOC, LOAD, READONLY, CODE1 .data 00000000 00000000 00000000 00000034 2**0CONTENTS, ALLOC, LOAD, DATA2 .bss 00000000 00000000 00000000 00000034 2**0ALLOC3 .rodata 00000008 00000000 00000000 00000034 2**2CONTENTS, ALLOC, LOAD, READONLY, DATA4 .comment 0000005e 00000000 00000000 0000003c 2**0CONTENTS, READONLY5 .note.GNU-stack 00000000 00000000 00000000 0000009a 2**0CONTENTS, READONLY6 .ARM.attributes 00000035 00000000 00000000 0000009a 2**0CONTENTS, READONLY
global_rodata_file.o 有七个 sections 分别是
- .text:代码段,由于没有代码,所以 .text 段的长度为 0
- .data:没有全局初始化的数据,所以 .data 段的长度为 0
- .bss:没有未初始化的全局数据,所以 .bss 段的长度为 0
- .rodata:数据段长度为 8,定义了两个 int 型全局只读常量并初始化,int 的长度是 4 个字节,两个 int 于是占用了 8 个字节,所以 .data 段的长度为 8。
- .comment:存放一些 GNU 的通用信息
- .note.GNU-stack:GNU 的注释信息
- .ARM.attributes:编译器相关信息
使用下面命令查看详细信息
arm-none-linux-gnueabihf-objdump -s -d global_rodata_file.o >global_rodata_file.info
命令结果如下
global_rodata_file.o: file format elf32-littlearmContents of section .rodata:0000 03000000 04000000 ........
Contents of section .comment:0000 00474343 3a202847 4e552054 6f6f6c63 .GCC: (GNU Toolc0010 6861696e 20666f72 20746865 20412d70 hain for the A-p0020 726f6669 6c652041 72636869 74656374 rofile Architect0030 75726520 31302e33 2d323032 312e3037 ure 10.3-2021.070040 20286172 6d2d3130 2e323929 29203130 (arm-10.29)) 100050 2e332e31 20323032 31303632 3100 .3.1 20210621.
Contents of section .ARM.attributes:0000 41340000 00616561 62690001 2a000000 A4...aeabi..*...0010 05372d41 00060a07 41080109 020a030c .7-A....A.......0020 01120414 01150117 03180119 011a021c ................0030 011e0622 01 ...".
- 由于还未链接,所以 .rodata 段的起始地址为 0。
main.o
objdump 解析命令
arm-none-linux-gnueabihf-objdump -h main.o >main.sec
objdump 解析结果:section,以及对应的 VMA 和 LMA
main.o: file format elf32-littlearmSections:
Idx Name Size VMA LMA File off Algn0 .text 00000064 00000000 00000000 00000034 2**1CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE1 .data 00000000 00000000 00000000 00000098 2**0CONTENTS, ALLOC, LOAD, DATA2 .bss 00000000 00000000 00000000 00000098 2**0ALLOC3 .comment 0000005e 00000000 00000000 00000098 2**0CONTENTS, READONLY4 .note.GNU-stack 00000000 00000000 00000000 000000f6 2**0CONTENTS, READONLY5 .ARM.attributes 00000035 00000000 00000000 000000f6 2**0CONTENTS, READONLY
main.o 有六个 sections 分别是
- .text:代码段,文件中定义了几个函数,所以 .text 的数据长度不为 0
- .data:没有全局初始化的数据,所以 .data 段的长度为 0
- .bss:没有未初始化的全局数据,所以 .bss 段的长度为 0
- .comment:存放一些 GNU 的通用信息
- .note.GNU-stack:GNU 的注释信息
- .ARM.attributes:编译器相关信息
使用下面命令查看详细信息
arm-none-linux-gnueabihf-objdump -s -d main.o >main.info
命令结果如下
main.o: file format elf32-littlearmContents of section .text:0000 80b582b0 00af7860 396040f2 0003c0f2 ......x`9`@.....0010 00031a68 40f20003 c0f20003 1b681946 ...h@........h.F0020 1046fff7 feff0246 40f20003 c0f20003 .F.....F@.......0030 1a6040f2 0003c0f2 00031a68 40f20003 .`@........h@...0040 c0f20003 1b681946 1046fff7 feff0246 .....h.F.F.....F0050 40f20003 c0f20003 1a600023 18460837 @........`.#.F.70060 bd4680bd .F..
Contents of section .comment:0000 00474343 3a202847 4e552054 6f6f6c63 .GCC: (GNU Toolc0010 6861696e 20666f72 20746865 20412d70 hain for the A-p0020 726f6669 6c652041 72636869 74656374 rofile Architect0030 75726520 31302e33 2d323032 312e3037 ure 10.3-2021.070040 20286172 6d2d3130 2e323929 29203130 (arm-10.29)) 100050 2e332e31 20323032 31303632 3100 .3.1 20210621.
Contents of section .ARM.attributes:0000 41340000 00616561 62690001 2a000000 A4...aeabi..*...0010 05372d41 00060a07 41080109 020a030c .7-A....A.......0020 01120414 01150117 03180119 011a021c ................0030 011e0622 01 ...".Disassembly of section .text:00000000 <main>:0: b580 push {r7, lr}2: b082 sub sp, #84: af00 add r7, sp, #06: 6078 str r0, [r7, #4]8: 6039 str r1, [r7, #0]a: f240 0300 movw r3, #0e: f2c0 0300 movt r3, #012: 681a ldr r2, [r3, #0]14: f240 0300 movw r3, #018: f2c0 0300 movt r3, #01c: 681b ldr r3, [r3, #0]1e: 4619 mov r1, r320: 4610 mov r0, r222: f7ff fffe bl 0 <test_func>26: 4602 mov r2, r028: f240 0300 movw r3, #02c: f2c0 0300 movt r3, #030: 601a str r2, [r3, #0]32: f240 0300 movw r3, #036: f2c0 0300 movt r3, #03a: 681a ldr r2, [r3, #0]3c: f240 0300 movw r3, #040: f2c0 0300 movt r3, #044: 681b ldr r3, [r3, #0]46: 4619 mov r1, r348: 4610 mov r0, r24a: f7ff fffe bl 0 <test_func>4e: 4602 mov r2, r050: f240 0300 movw r3, #054: f2c0 0300 movt r3, #058: 601a str r2, [r3, #0]5a: 2300 movs r3, #05c: 4618 mov r0, r35e: 3708 adds r7, #860: 46bd mov sp, r762: bd80 pop {r7, pc}
-
由于还未链接,所以代码起始地址为
0
-
第 22 行可以看到一个跳转指令,表示需要链接的位置
f7ff fffe bl 0 <test_func>
有一个标签
<test_func>
,bl 目前跳转的地方是 0 地址,后期连接器会把这个值改回来 -
变量的赋值时通过如下汇编语句实现,可以看到变量的值都是 0,后期链接器会将这两个值改为真正的
test_data1
和test_data2
等数据。
test_data1:a: f240 0300 movw r3, #0 e: f2c0 0300 movt r3, #0 12: 681a ldr r2, [r3, #0] 20: 4610 mov r0, r2
movw
将一个 16 位数据移动到寄存器的低 16 位,并把高 16 位清零。movt
将一个 16 位数据移动到寄存器的高 16 位,低 16 位不处理。- 所以此时 r3 寄存器的值为 0,接着将 r3 寄存器的值解引用的值,加载到 r2
- 函数调用时,将 r2 寄存器的值放到 r0 寄存器中,r0 在函数调用时,传递的是第一个参数
test_data2:
14: f240 0300 movw r3, #0 18: f2c0 0300 movt r3, #0 1c: 681b ldr r3, [r3, #0] 1e: 4619 mov r1, r3
movw
将一个 16 位数据移动到寄存器的低 16 位,并把高 16 位清零。movt
将一个 16 位数据移动到寄存器的高 16 位,低 16 位不处理。- 所以此时 r3 寄存器的值为 0,接着将 r3 寄存器的值解引用的值,加载到 r3
- 函数调用时,将 r3 寄存器的值放到 r1 寄存器中,r1 在函数调用时,传递的是第二个参数
链接
上面描述中有五个 .o 文件,分别是
- global_bss_file.o 定义了 2 个未初始化的全局变量
- global_data_fle.o 定义了 2 个初始化的全局变量
- global_function_file.o 定义了一个函数
- global_rodata_file.o 定义了 2 个只读常量
- main.o 使用上面定义的函数和变量
在链接之前并不知道数据的具体数值,也不知道调用函数的函数位置,因此事先会把不知道的信息空出来,等到链接的时候再合并。因此接下来要观察链接的结果。
使用链接命令
arm-none-linux-gnueabihf-ld global_bss_file.o global_data_fle.o global_function_file.o global_rodata_file.o main.o -T link.lds -o test
得到输出文件 test
使用
arm-none-linux-gnueabihf-objdump -h test > test.sec
命令返回结果如下
test: file format elf32-littlearmSections:
Idx Name Size VMA LMA File off Algn0 .text 00000080 00900000 00900000 00010000 2**1CONTENTS, ALLOC, LOAD, READONLY, CODE1 .rodata 00000008 00900080 00900080 00010080 2**2CONTENTS, ALLOC, LOAD, READONLY, DATA2 .data 00000008 80000000 80000000 00020000 2**2CONTENTS, ALLOC, LOAD, DATA3 .bss 00000008 80000008 80000008 00020008 2**2ALLOC4 .comment 0000005d 00000000 00000000 00020008 2**0CONTENTS, READONLY5 .ARM.attributes 00000035 00000000 00000000 00020065 2**0CONTENTS, READONLY
test 有六个 sections 分别是
- .text
- .rodata
- .data
- .bss
- .comment
- .ARM.attributes。
可以看到链接后的 test 文件的 .text,.data,.rodata,和 .bss 等段的 size 是多个 .o 文件的和。
使用下面命令查看详细信息
arm-none-linux-gnueabihf-objdump -s -d test >test.info
命令结果如下
test: file format elf32-littlearmContents of section .text:900000 80b483b0 00af7860 39607a68 3b681344 ......x`9`zh;h.D900010 18460c37 bd465df8 047b7047 80b582b0 .F.7.F]..{pG....900020 00af7860 396040f2 0003c8f2 00031a68 ..x`9`@........h900030 40f20403 c8f20003 1b681946 1046fff7 @........h.F.F..900040 dfff0246 40f20803 c8f20003 1a6040f2 ...F@........`@.900050 8003c0f2 90031a68 40f28403 c0f29003 .......h@.......900060 1b681946 1046fff7 cbff0246 40f20c03 .h.F.F.....F@...900070 c8f20003 1a600023 18460837 bd4680bd .....`.#.F.7.F..
Contents of section .rodata:900080 03000000 04000000 ........
Contents of section .data:80000000 01000000 02000000 ........
Contents of section .comment:0000 4743433a 2028474e 5520546f 6f6c6368 GCC: (GNU Toolch0010 61696e20 666f7220 74686520 412d7072 ain for the A-pr0020 6f66696c 65204172 63686974 65637475 ofile Architectu0030 72652031 302e332d 32303231 2e303720 re 10.3-2021.070040 2861726d 2d31302e 32392929 2031302e (arm-10.29)) 10.0050 332e3120 32303231 30363231 00 3.1 20210621.
Contents of section .ARM.attributes:0000 41340000 00616561 62690001 2a000000 A4...aeabi..*...0010 05372d41 00060a07 41080109 020a030c .7-A....A.......0020 01120414 01150117 03180119 011a021c ................0030 011e0622 01 ...".Disassembly of section .text:00900000 <test_func>:900000: b480 push {r7}900002: b083 sub sp, #12900004: af00 add r7, sp, #0900006: 6078 str r0, [r7, #4]900008: 6039 str r1, [r7, #0]90000a: 687a ldr r2, [r7, #4]90000c: 683b ldr r3, [r7, #0]90000e: 4413 add r3, r2900010: 4618 mov r0, r3900012: 370c adds r7, #12900014: 46bd mov sp, r7900016: f85d 7b04 ldr.w r7, [sp], #490001a: 4770 bx lr0090001c <main>:90001c: b580 push {r7, lr}90001e: b082 sub sp, #8900020: af00 add r7, sp, #0900022: 6078 str r0, [r7, #4]900024: 6039 str r1, [r7, #0]900026: f240 0300 movw r3, #090002a: f2c8 0300 movt r3, #32768 ; 0x800090002e: 681a ldr r2, [r3, #0]900030: f240 0304 movw r3, #4900034: f2c8 0300 movt r3, #32768 ; 0x8000900038: 681b ldr r3, [r3, #0]90003a: 4619 mov r1, r390003c: 4610 mov r0, r290003e: f7ff ffdf bl 900000 <test_func>900042: 4602 mov r2, r0900044: f240 0308 movw r3, #8900048: f2c8 0300 movt r3, #32768 ; 0x800090004c: 601a str r2, [r3, #0]90004e: f240 0380 movw r3, #128 ; 0x80900052: f2c0 0390 movt r3, #144 ; 0x90900056: 681a ldr r2, [r3, #0]900058: f240 0384 movw r3, #132 ; 0x8490005c: f2c0 0390 movt r3, #144 ; 0x90900060: 681b ldr r3, [r3, #0]900062: 4619 mov r1, r3900064: 4610 mov r0, r2900066: f7ff ffcb bl 900000 <test_func>90006a: 4602 mov r2, r090006c: f240 030c movw r3, #12900070: f2c8 0300 movt r3, #32768 ; 0x8000900074: 601a str r2, [r3, #0]900076: 2300 movs r3, #0900078: 4618 mov r0, r390007a: 3708 adds r7, #890007c: 46bd mov sp, r790007e: bd80 pop {r7, pc}
观察链接前后的差异
地址变化
- 链接之后,代码起始地址为:0x00900000
- 链接之后,数据起始地址为:0x80000000
main.o
- 原先 bl 0 位置被连接器替换为了 bl 900000。而 900000 刚好是 test_func 的代码地址
90003e: f7ff ffdf bl 900000 <test_func>
- 全局变量的地址
900026: f240 0300 movw r3, #0 90002a: f2c8 0300 movt r3, #32768 ; 0x8000 90002e: 681a ldr r2, [r3, #0] 90003c: 4610 mov r0, r2
movw
将一个 16 位数据移动到寄存器的低 16 位,并把高 16 位清零。movt
将一个 16 位数据移动到寄存器的高 16 位,低 16 位不处理。- 所以此时 r3 寄存器的值为
0x80000000
- 将 r3 寄存器的值解引用后放到 r2 寄存器中,所以此时 r2 寄存器的值为
0x01
- 函数调用时,将 r2 寄存器的值给到 r0,所以
r0
的值为0x01
表示第一个参数
900030: f240 0304 movw r3, #4 900034: f2c8 0300 movt r3, #32768 ; 0x8000 900038: 681b ldr r3, [r3, #0] 90003a: 4619 mov r1, r3
movw
将一个 16 位数据移动到寄存器的低 16 位,并把高 16 位清零。movt
将一个 16 位数据移动到寄存器的高 16 位,低 16 位不处理。- 所以此时 r3 寄存器的值为
0x80000004
- 将 r3 寄存器的值解引用后放到 r3 寄存器中,所以此时 r3 寄存器的值为
0x02
- 函数调用时,将 r3 寄存器的值给到 r1,所以
r1
的值为0x02
表示第二个参数