use*_*761 5 x86 assembly addressing-mode
我在" 从头开始编程 "一书中已经阅读了以下内容:
处理器有许多不同的访问数据的方式,称为寻址模式.最简单的模式是立即模式,其中要访问的数据嵌入在指令本身中.例如,如果我们想要将寄存器初始化为0,而不是给计算机一个地址来读取0,我们将指定立即模式,并给它数字0.
在寄存器寻址模式中,指令包含要访问的寄存器,而不是存储器位置.其余模式将处理地址.
这是否意味着例如指令mov eax, 123处于立即模式和 寄存器寻址模式?
它不是具有特定寻址模式的整个指令,而是每个操作数分开. 在您的mov eax, 123示例中,您要说源是立即操作数,目标是寄存器操作数.
或者你可以说,如果你想谈论整个指令所采用的形式,该指令的机器代码将使用mov r, imm32编码mov.(还有一种mov r/m, imm32形式mov,但它更长,所以一个好的汇编程序只会选择,如果目标实际上是内存).
但是,当其中一个操作数是寄存器时,为方便起见,您可以根据需要说"指令使用[base+index]寻址模式".但实际上它是你所谈论的内存操作数,而不是整个指令.特别是如果你将寄存器和立即数视为"寻址模式",即使没有涉及存储器地址.
而且,通常当人们说"寻址模式"时,他们谈的是内存地址.技术上的x86,大多数指令具有一个寄存器和一个寄存器/存储器操作数,所以之间的差add eax, ecx和add eax, [ecx]只我认为在1位mod/rm字节(下面的操作码).
一些指令有两个内存操作数.例如,push qword [rdi + rax*8]显式加载[rdi + rax*8]并隐式存储[rsp].另一个例子是字符串指令movs和cmps,其使用[rdi]和[rsi]含蓄.
但是没有指令有两个通用的r/m操作数,可以让你使用任意选择的正常寻址模式.因此x86指令最多只有一个mod/rm字节.
将立即操作数称为"寻址模式"是否有争议,因为数据不是来自任何地方.这是教学的一部分.此外,指令的立即操作数形式具有与reg,reg/mem形式不同的操作码.
另请注意,大多数可以具有内存源或内存目标的整数指令都有两个操作码:一个用于op r/m, r,一个用于op r, r/m.(例如,请参阅参考资料手册条目and,以及更多指向x86标签wiki中文档的链接.)无论如何,and eax, ecx可以用两个操作码中的任何一个进行编码,这取决于汇编程序.选择对性能没有影响.