- 论坛徽章:
- 0
|
原帖由 albcamus 于 2008-7-16 17:22 发表 ![]()
mik版主写过a64汇编器, 是不是 对Unix来说, 只有as作者才需要关注REX?
偶最善此道了。
你提到的问题并不复杂。 实际上只是汇编语言层面的语法而已。
1、从本质上讲与你所说的 -1 完全无关,也没有什么 0x7fffffff 的制约。
2、出现 addq $0xffffffff, %rax 错误的原因完全是语法问题,或者说是 gas 这个汇编器的语法限制,当然在 masm 的语法也有这方面的限制。
从 amd64 的指令本质来说:add rax, 0FFFFFFFF 是完全正确的。
反而 add rax, 0FFFFFFFFFFFFFFFF 这是错误的。因为,x86_64 指令要求的立即数除了mov,push 指令外的其它指令,是不允许有64位立即数的。
然而,从汇编语法上来讲:x86 & x64 的指令格式绝大部分要求:源操作数与目的操作数的大小要一致,汇编器在进行翻译为机器码时,就会遵从指令的本质。
3、所以,基于第2条的论述:
addq $0xffffffffffffffff, %rax 这条指令译为机器码是:
49 05 FF FF FF FF // 共 6 个字节,而不是 10 个字节
同样: 若是: 49 05 FF FF FF FF // 会被 objdump 之类的程序显示为: addq $0xFFFFFFFFFFFFFFFF, %rax
// 而不会显示为: addq $0xFFFFFFFF, %rax
总结: 这可以说是语法,或者是显示上的问题,而不论是 AMD 或 Intel 的官方文档上说的是:指令的本质问题。
所以,若遇到另一个汇编编译器,对 add rax, 0xFFFFFFFF 这条指令判断是正确的话,也不要觉得奇怪,这是它的语法上可以通过
我自己写的 a64 是按本质来定语法的
4、另外,扯一下, add 与 mov 这两类指令的 64 位立即数编码的区别:
addq $0xffffffffffffffff, %rax // 基上所述是: 6 个字节
movq $0xffffffffffffffff, %rax // 则是实打实的: 10 个字节。 mov 与 push 指令是唯一可接受64位立即数的两条指令 |
|