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

我正在使用测试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()
部分生成长输出:

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的答案显然是解决方案