我正在通过x86 Intel文档上的ADD指令,一次一行,并试图重现它,以便我可以了解他们晦涩的符号是如何工作的,并弄清楚如何在没有gcc/clang/llvm/等的情况下生成机器码。
我目前被困在81
操作码对上:
81 /0 iw ADD r/m16, imm16 MI Valid Valid Add imm16 to r/m16.
81 /0 id ADD r/m32, imm32 MI Valid Valid Add imm32 to r/m32.
NASM指令调用将生成匹配这些模式的输出并为每个模式生成以81
开头的输出的两个示例(每个示例一个)是什么?
当我尝试我认为可以工作时,我得到完全不同的输出:
add ax, 6553
就变成:
66 05 99 19
从这个:bits 64
global start
section .text
start:
ADD ax, 6553
和
nasm -f macho64 test.asm
我可以得到83
的工作,如:
83 /0 ib ADD r/m16, imm8
工作原理如下:
bits 16
global start
section .text
start:
add ax, 1
但是这81个都不行,而且只有imm16
不同,我不明白。
开头某处提到:66
前缀在16位和32位操作数大小之间切换。在16位模式下,默认为16位操作数大小。在32位和64位模式下,32位是默认的操作数大小。由于指令列表适用于所有操作模式(除非另有说明),它不会显示66
前缀的使用位置,因为它总是以相同的方式用于标量指令(但要注意SSE指令,其中前缀用于不同的目的)。
关于add ax, 6553
指令:汇编程序在这里选择较短的add ax, imm16
编码。选择一个不同于ax
的寄存器来避免这种影响。
也许试试
add cx, 1234
add ecx, 1234
和
add rcx, 1234