我正在查看英特尔指令集手册,看起来有两种不同形式的ADC匹配/编码ADC EAX, ECX如下:
ADC r/m32, r32 (11 /r , which encodes to 11C8)
Run Code Online (Sandbox Code Playgroud)
要么
ADC r32, r/m32 (13 /r, which encodes to 13C1)
Run Code Online (Sandbox Code Playgroud)
我的问题是(因为我做了正确的数学),是11C8和13C1相同呢?汇编程序在选择一种编码而不是另一种编码时会考虑哪些因素?问题是从实现汇编程序的角度来看,所以问题通常不在于这个特定的假设指令.
如果这是一个冗长的答案,请指出我正确的方向,因为我在谷歌上搜索失败.
看完这个堆栈溢出的答案,而这个文件,我还是不明白之间的差别movq和movabsq.
我目前的理解是movabsq,第一个操作数是一个64位立即数操作数,而movq符号扩展一个32位立即数操作数.从上面引用的第二个文件:
将立即数据移动到64位寄存器可以通过
movq指令进行,该指令将签署扩展32位立即值,或者movabsq在需要完整的64位立即数时使用指令.
在第一篇参考文献中,彼得说:
有趣的实验:
movq $0xFFFFFFFF, %rax可能不可编码,因为它不能用符号扩展的32位立即数表示,并且需要imm64编码或%eax目标编码.
但是,当我组装/运行它时似乎工作正常:
.section .rodata
str:
.string "0x%lx\n"
.text
.globl main
main:
pushq %rbp
movq %rsp, %rbp
movl $str, %edi
movq $0xFFFFFFFF, %rsi
xorl %eax, %eax
call printf
xorl %eax, %eax
popq %rbp
ret
Run Code Online (Sandbox Code Playgroud)
$ clang file.s -o file && ./file
打印0xffffffff.(这适用于较大的值,例如,如果你输入一些额外的"F").movabsq生成相同的输出.
Clang是在推断我想要的吗?如果是,是否有仍然是受益movabsq过度movq?
我错过了什么?
我为amd64编写了这个小程序集文件.代码的作用对于这个问题并不重要.
.globl fib
fib: mov %edi,%ecx
xor %eax,%eax
jrcxz 1f
lea 1(%rax),%ebx
0: add %rbx,%rax
xchg %rax,%rbx
loop 0b
1: ret
Run Code Online (Sandbox Code Playgroud)
然后我继续组装,然后在Solaris和Linux上反汇编.
$ as -o y.o -xarch=amd64 -V y.s
as: Sun Compiler Common 12.1 SunOS_i386 Patch 141858-04 2009/12/08
$ dis y.o
disassembly for y.o
section .text
0x0: 8b cf movl %edi,%ecx
0x2: 33 c0 xorl %eax,%eax
0x4: e3 0a jcxz +0xa <0x10>
0x6: 8d 58 01 leal 0x1(%rax),%ebx
0x9: 48 03 c3 addq %rbx,%rax
0xc: 48 93 xchgq %rbx,%rax …Run Code Online (Sandbox Code Playgroud) 看http://ref.x86asm.net/coder32.html我发现两个匹配语句的操作码
xor eax,eax
1)操作码31 XOR r/m16/32 r16/32
2)操作码33 XOR r16/32 r/m16/32
两者都指操作数1和操作数2的32位寄存器.那么,XORing两个32位寄存器的这种特殊情况有什么不同吗?
为什么NASM在两个寄存器之间组装MOV指令时使用0x89操作码(137)?
以下是使用NASM汇编的代码示例:
55 push ebp
89E5 mov ebp, esp
83EC04 sub esp, byte +0x4
31C0 xor eax, eax
C9 leave
C3 ret
Run Code Online (Sandbox Code Playgroud)
我想要这样的东西:
55 push ebp
8BEC mov ebp, esp
83EC04 sub esp, byte +0x4
33C0 xor eax, eax
C9 leave
C3 ret
Run Code Online (Sandbox Code Playgroud)
我想要0x8B的原因是:如果你查看MOV指令的二进制表示,它在NASM中看起来像这样:
Opcode Mod Reg R/M
10001001 11 100 101 (89 E5)
Run Code Online (Sandbox Code Playgroud)
令人困惑的部分是reg操作数是第二个.
NASM的语法是这样的:0x89 11 source_reg destination_reg和
MOV指令是mov destination_reg, source_reg