C 反汇编的arm代码似乎有一个错误
我正在使用测试C文件为嵌入式ARM芯片编译一些测试代码C 反汇编的arm代码似乎有一个错误,c,arm,embedded,arm-none-eabi-gcc,C,Arm,Embedded,Arm None Eabi Gcc,我正在使用测试C文件为嵌入式ARM芯片编译一些测试代码 test.c如下所示: int main(){ *(int*)0xFFFFF400 = 7; } 我使用以下命令编译该文件 arm-none-eabi-gcc -march=armv4 -mtune=arm7tdmi -specs=nosys.specs -Wall -o test test.c 它毫无怨言地编译,然后我用 arm-none-eabi-objdump -d ./test 它通过以下main()部分生成长输出: 00
test.c
如下所示:
int main(){
*(int*)0xFFFFF400 = 7;
}
我使用以下命令编译该文件
arm-none-eabi-gcc -march=armv4 -mtune=arm7tdmi -specs=nosys.specs -Wall -o test test.c
它毫无怨言地编译,然后我用
arm-none-eabi-objdump -d ./test
它通过以下main()
部分生成长输出:
00008018 <main>:
8018: e3e03000 mvn r3, #0
801c: e3a02007 mov r2, #7
8020: e3a00000 mov r0, #0
8024: e5032bff str r2, [r3, #-3071] ; 0xfffff401
8028: e1a0f00e mov pc, lr
00008018:
8018:e3e03000 mvn r3,#0
801c:e3a02007 mov r2,#7
8020:e3a00000 mov r0,#0
8024:E5032BF str r2[r3,#-3071];0xfffff401
8028:e1a0f00e mov pc,lr
为什么它说的是0xfffff401而不是0xfffff400?为什么要减去3071而不是3072?mvn指令将其操作数的位逆写入寄存器。0的位逆是所有1位,在2的补码中表示−1.然后地址
[r3,#-3071]
是−1 + −3071 = −3072
我不知道编译器为什么选择将其寻址设置为基础−1而不是0。这是否回答了您的问题?大概我的直觉告诉我那是另一回事。。。这不是跳转指令,而是内存存储指令。此外,这与thumb指令无关,它显然是一条正在执行的32位ARM指令。
mvn
指令将其操作数的位逆写入寄存器。0的位逆是所有1位,在2的补码中表示−1.然后地址[r3,#-3071]
是−1 + −3071 = −如果它与thumb模式无关,那么您可能已经设法让编译器相信这是Linux内核代码或类似代码。Linux特别使用一个系统,其中地址中的MSB集表示内核代码。这可以解释为什么,因为这是物理地址(对吗?)而不是虚拟地址,所以没有任何意义。是否有任何复杂的MMU设置或类似的设置?没有。Eric的答案显然是解决方案