2014-01-29 253 views
8

我在讀了以下定義爲系統調用:cmpq指令是做什麼的?

.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指令究竟做了什麼?

回答

11

cmpq $-4095, %rax將64位寄存器%rax與立即值-4095進行比較 - 爲了比較的目的,該值被符號擴展爲64位。即,-4095具有64位的2的補碼錶示:ffff ffff ffff f001

cmp指令設置標誌寄存器,因爲這將要sub(減去)第二個操作數從第一 - 「第二」和「第一」中被反向AT & T語法。實際上,根據以下結果設置標誌:(RAX - (- 4095))(RAX + 4095),在2的補碼中相同。

其中一個標誌集是進位標誌(CF),它在(無符號)溢出時置位。 jae指令(jump-if-above-or-equal)實際上是jnc的「別名」(如果不能進行跳轉)。換句話說,如果(RAX + 4095)確實是不是,在2的補碼中,對於RAX的值在[-4095, -1]範圍內,這將是正確的。 (記住2如何補碼算術包裝)。 Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2


的指令,包括cmpjae(或j<cond>)中有描述。

在[Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1的3.4.3節中描述了[E]標誌寄存器(以及算術標誌表示的內容)。