web-dev-qa-db-ja.com

cmpq命令は何をしますか?

私は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命令は正確に何をしますか?

12
brooks94

cmpq $-4095, %raxは、64ビットレジスタ%raxを即値-4095と比較します。値は、比較のために64ビットに符号拡張されます。つまり、-4095には64ビット2の補数表現があります:ffff ffff ffff f001

cmp命令は、AT&T構文で逆になっている最初のオペランドから2番目のオペランドのsub(減算)の場合と同じようにフラグレジスタを設定します。事実上、フラグは次の結果に従って設定されます:(RAX - (- 4095))または(RAX + 4095)、2の補数で同じです。

設定されるフラグの1つは、carryフラグ(CF)であり、(符号なし)オーバーフローに設定されます。 jae命令(jump-if-above-or-equal)は、実際にはjnc(jump-if-not-carry)の「エイリアス」です。言い換えると、(RAX + 4095)notを実行する場合、分岐が実行されます。 2の補数では、これは次の範囲のRAXの値に当てはまります:[-4095, -1]。 (2の補数演算がどのようにラップするかを覚えておいてください)。


cmpおよびjae(またはj<cond>)を含む手順については、以下で説明します。 インテル®64およびIA-32アーキテクチャーソフトウェア開発者マニュアル、第2巻

[E] FLAGSレジスタ(および算術フラグが示すもの)については、 Intel®64およびIA-32アーキテクチャソフトウェア開発者マニュアル、第1巻 のセクション3.4.3で説明されています。

18
Brett Hale