x86-64 指令“shrb %​​dil”是什么意思?

ndr*_*zza 1 x86 assembly x86-64 att

我知道这shrb代表逻辑右移。通常它与两个参数一起使用,shrb amount, %register. 但是,在我查看的代码中,它没有使用移位量 - 只指定了一个寄存器:

shrb %dil
Run Code Online (Sandbox Code Playgroud)

其中%dil代表 的最低有效字节%rdi

现在上面的命令是否意味着我们右移 1?你会怎么去发现这个?有没有办法以某种方式执行命令,看看会发生什么?该文档对于提供有关省略班次金额时会发生什么的信息没有帮助:https : //docs.oracle.com/cd/E19253-01/817-5477/817-5477.pdf

Cod*_*ray 5

这是 AT&T/GAS 语法,与 Intel 语法非常不同。在 Intel 语法中,等效指令为:

shr  dil, 1
Run Code Online (Sandbox Code Playgroud)

它是 64 位长模式代码,将edi寄存器的最低 8 位(指使用dil助记符)右移 1 位。(目标操作数的)最低有效位被移入进位标志(CF),最高有效位被清除。( 的标准行为shr。)

请注意,在您的代码中,shr助记符后缀为b. 这表明它是一个byte 大小的操作。Intel 语法使用操作数之一(例如, DWORD PTR)上的注释来消除歧义,而 AT&T 语法使用指令后缀:b字节、w字、l长字、q四字等。

在这种情况下,b后缀实际上是可选的,即使在 AT&T 语法中也是如此,因为目标操作数是一个 8 位寄存器,使得指令没有歧义。但是,Gnu 工具通常会为所有指令添加后缀以保持一致性,即使没有歧义。这可能是您的代码的来源。

此外,在 AT&T 语法中shrsar、 和shl指令通常在为 1 时省略移位量。 换句话说,将其写为在技术上是正确的:

shrb  $1, %dil
Run Code Online (Sandbox Code Playgroud)

但是我见过的大多数工具都不会使用这种形式,尤其是 Gnu 反汇编器。(注意 AT&T 和 Intel 语法之间的另一个区别:目标和源操作数是颠倒的。)

移位量为1时省略可能是历史原因。x86 上的每条移位指令实际上有三种不同的编码:一种以常数 1 移位,一种以立即数移位,一种以cl寄存器内容移位。直到 286 才引入了立即移位编码,这就是为什么有一个单独的(较短的)移位编码。如今,您可以将 shift-by-1 编码为 shift-by-immediate-1,但没有理智的汇编程序会这样做。尽管如此,AT&T/GAS 语法在符号中保留了这一历史遗产。