问题描述
我正在使用测试 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
为什么显示 0xfffff401 而不是 0xfffff400?为什么是减去3071而不是3072?
解决方法
mvn
指令将其操作数的按位反转写入寄存器。 0 的按位逆是全 1 位,用二进制补码表示 -1。那么地址[r3,#-3071]
是-1 + -3071 = -3072。
我不知道为什么编译器选择将其寻址基于 -1 而不是 0。