cmpq指令有什么作用?

时间:2014-01-29 19:13:02

标签: assembly x86 x86-64

我正在阅读系统调用的以下定义:

.text
.globl syscall
.type   syscall,%function
.align 16
syscall:
    movq %rdi, %rax     /* Syscall number -> rax.  */
    movq %rsi, %rdi     /* shift arg1 - arg5.  */
    movq %rdx, %rsi
    movq %rcx, %rdx
    movq %r8, %r10
    movq %r9, %r8
    movq 8(%rsp),%r9    /* arg6 is on the stack.  */
    syscall         /* Do the system call.  */
    cmpq $-4095, %rax   /* Check %rax for error.  */
    jae __syscall_error     /* Branch forward if it failed.  */
    ret         /* Return to caller.  */

.size syscall,.-syscall

我看到它解释了行cmpq $-4095 %rax确定%rax是否包含介于-1和-4095之间的值。它是如何做到的? cmpq指令究竟做了什么?

1 个答案:

答案 0 :(得分:17)

cmpq $-4095, %rax将64位寄存器%rax与立即值-4095进行比较 - 为了进行比较,将值符号扩展为64位。即,-4095具有64位2的补码表示:ffff ffff ffff f001

cmp指令设置标志寄存器,因为第一个“{second”和第一个'的第二个操作数的sub(减法)在AT& T语法中被反转。实际上,标志是根据以下结果设置的:(RAX - (- 4095))(RAX + 4095),在2的补码中是相同的。

其中一个标志集是进位标志(CF),它被设置为(无符号)溢出。 jae指令(跳转 - 如果高于或等于)实际上是jnc的“别名”(如果不是进位则跳转)。换句话说,如果(RAX + 4095) 携带,则采取分支。在2的补码中,对于范围为RAX的{​​{1}}的值,情况也是如此。 (记住2的补码运算如何包装)。


说明,包括[-4095, -1]cmp(或jae),请参阅:Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2

[E] FLAGS寄存器(以及算术标志表示的内容)在Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1的第3.4.3节中描述。​​