Abh*_*ury 2 compiler-construction x86 assembly gcc arm
让我们用一个简单的C代码来设置寄存器:
int main()
{
int *a = (int*)111111;
*a = 0x1000;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我使用1级优化编译ARM(arm-none-eabi-gcc)代码时,汇编代码如下:
mov r2, #4096
mov r3, #110592
str r2, [r3, #519]
mov r0, #0
bx lr
Run Code Online (Sandbox Code Playgroud)
看起来地址111111被解析为最接近的4K边界(110592)并移动到r3,然后通过将519添加到110592(= 111111)来存储值4096(0x1000).为什么会这样?
在x86中,程序集很简单:
movl $4096, 111111
movl $0, %eax
ret
Run Code Online (Sandbox Code Playgroud)
这种编码背后的原因是因为x86具有可变大小的指令 - 从1个字节到16个字节(甚至可能更多的前缀).
ARM指令是32位宽(不计算Thumb模式),这意味着根本无法在单个操作码中编码所有32位宽常量(即时).
固定大小的体系结构通常使用一些方法来加载大常量:
1) movi #r1, Imm8 ; // Here Imm8 or ImmX is simply X least significant bits
2) movhi #r1, Imm16 ; // Here Imm16 loads the 16 MSB of the register
3) load #r1, (PC + ImmX); // use PC-relative address to put constant in code
4) movn #r1, Imm8 ; // load the inverse of Imm8 (for signed constants)
5) mov(i/n) #1, Imm8 << N; // where N=0,8,16,24
Run Code Online (Sandbox Code Playgroud)
可变大小的体系结构OTOH可以将所有常量放在一条指令中:
xx xx xx 00 10 00 00 11 11 11 00 ; // assuming that it takes 3 bytes to encode
; // the instruction and the addressing mode
; added with 4 bytes to encode the 4096 and 4 bytes to encode 0x00111111
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1810 次 |
| 最近记录: |