cmp汇编指令如何设置标志(X86_64 GNU Linux)

时间:2017-05-08 06:33:20

标签: assembly x86-64 att

这是一个简单的C程序:

void main()
{
       unsigned char number1 = 4;
       unsigned char number2 = 5;

       if (number1 < number2)
       {
               number1 = 0;
       }
}

所以我们在这里比较两个数字。在汇编中,它将使用cmp完成。 cmp的工作原理是从其他操作数中减去一个操作数。

现在cmp如何减去操作数?是从第二个减去第一个操作数还是反之?无论如何,这应该是这样的:

案例#1:

4 - 5 =(0000 0100 - 0000 0101)=(0000 0100 + 1111 1010 + 1)=(0000 0100 + 1111 1011)

= 1111 1111 = -1

因此,因为符号位= 1所以SF应该是1。

没有进位,所以CF应该是= 0.

案例#2:

5 - 4 =(0000 0101 - 0000 0100)=(0000 0101 + 1111 1011 + 1)

=(0000 0101 + 1111 1100)= 1 0000 0001

所以这里,CF应该是= 1

由于结果为正,因此SF应为= 0

现在我编译并运行程序(linux x86_64,gcc,gdb),在cmp指令之后放置一个断点来查看寄存器状态。

在cmp:

之后命中断点
Breakpoint 2, 0x0000000000400509 in main ()
(gdb) disassemble
Dump of assembler code for function main:
   0x00000000004004f6 <+0>:     push   %rbp
   0x00000000004004f7 <+1>:     mov    %rsp,%rbp
   0x00000000004004fa <+4>:     movb   $0x4,-0x2(%rbp)
   0x00000000004004fe <+8>:     movb   $0x5,-0x1(%rbp)
   0x0000000000400502 <+12>:    movzbl -0x2(%rbp),%eax
   0x0000000000400506 <+16>:    cmp    -0x1(%rbp),%al
=> 0x0000000000400509 <+19>:    jae    0x40050f <main+25>
   0x000000000040050b <+21>:    movb   $0x0,-0x2(%rbp)
   0x000000000040050f <+25>:    pop    %rbp
   0x0000000000400510 <+26>:    retq
End of assembler dump.

执行cmp后注册转储:

(gdb) info reg
rax            0x4  4
rbx            0x0  0
rcx            0x0  0
rdx            0x7fffffffe608   140737488348680
rsi            0x7fffffffe5f8   140737488348664
rdi            0x1  1
rbp            0x7fffffffe510   0x7fffffffe510
rsp            0x7fffffffe510   0x7fffffffe510
r8             0x7ffff7dd4dd0   140737351863760
r9             0x7ffff7de99d0   140737351948752
r10            0x833    2099
r11            0x7ffff7a2f950   140737348041040
r12            0x400400 4195328
r13            0x7fffffffe5f0   140737488348656
r14            0x0  0
r15            0x0  0
rip            0x400509 0x400509 <main+19>
eflags         0x297    [ CF PF AF SF IF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0
(gdb)

因此我们可以看到,在执行cmp之后,CF = 1,SF = 1。

因此实际结果标志(CF = 1&amp; SF = 1)不等于我们在

中计算的标志

案例#1(CF = 0&amp; SF = 1)或案例#2(CF = 1&amp; SF = 0)

那是怎么回事? cmp实际上是如何设置标志的?

0 个答案:

没有答案