cmpq指令是做什么用的?

19

我正在阅读syscall的下列定义:

.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个回答

26

cmpq $-4095, %rax比较64位寄存器%rax和立即数-4095,该值在比较时被符号扩展为64位。即-4095具有64位的二进制补码表示:ffff ffff ffff f001

cmp指令会设置标志寄存器,就像对第一个操作数减去第二个操作数(在AT&T语法中,第二个和第一个被颠倒)。实际上,根据以下结果设置标志:(RAX - (- 4095))(RAX + 4095),在二进制补码中是相同的。

其中一个设置的标志是进位标志(CF),它在(无符号)溢出时设置。 jae指令(跳转如果大于等于)实际上是jnc(跳转如果没有进位)的“别名”。换句话说,如果(RAX + 4095)不进位,则执行跳转。在二进制补码中,这对于RAX的值在范围[-4095,-1]内成立。(记住二进制补码算术如何进行包装)。


包括cmpjae(或j<cond>)在内的指令在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节中进行了描述。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接