32位汇编语言学习笔记(6)--设置条件码



条件码保存在条件码寄存器中,用于描述算术和最近逻辑操作的属性。最常用的条件码有:

CF:进位标志。

ZF:零标志。

SF:符号标志。

OF:溢出标志。

 

算术和逻辑操作指令都会修改条件码的值,但是leal指令不会修改条件码的值。

此外,cmp指令和test指令也会修改条件码。

cmp S2, S1 S1-S2的结果与0进行比较,分别对应大于0,等于0和小于0三种情况,不同比较结果会设置不同的条件码的值。

test S2, S1 测试S1 & S2结果值,分别对应大于0,等于0和小于0三种情况,不同比较结果会设置不同的条件码的值。

 

set系列指令会根据条件码的值设置目的寄存器的值:

sete D,等于0D=ZF

setz D,与sete相同。

setne D,不等于0D=~ZF

setnz D,与setne相同。

sets D,负数,D=SF

setns D,非负数,D=~SF

setg D,有符号大于,D=~(SF ^ OF)& ~ZF

setnle D,与setg D相同。

setge D,有符号大于等于,D=~(SF ^ OF)

setnl D,与setge相同。

setl D,有符号小于,D=SF ^ OF

setnge D,与setl D相同。

setle D,有符号小于等于,D=(SF ^ OF)| ZF

setng D,与setle D相同。

seta D,无符号大于,D=~CF &~ZF

setnbe D,与seta D相同。

setae D,无符号大于等于,D=~CF

setnb D,与setae D相同。

setb D,无符号小于,D= CF

setnae D,与setb D相同。

setbe D,无符号小于等于,D= CF | ZF

setna D,与setbe相同。

 

示例:

char ctest_1(int a, int b)

{

 char t1 =         a <             b;

 return t1;

}

 

gcc -O1 -S -m32 ctest_1.c

 

ctest_1:

       pushl   %ebp

       movl    %esp, %ebp

       movl    12(%ebp), %eax

       cmpl    %eax, 8(%ebp)  //比较ab

       setl    %al //如果a<bal会设置成1,否则设置成0

       movzbl  %al, %eax //eax的高位3字节用0来填充。

       popl    %ebp

       ret

 

char ctest(int a, int b, int c)

{

 char t1 =         a <             b;

 char t2 =         b <  (unsigned)   a;

 char t3 = (short) c >= (short)   a;

 char t4 = (char) a != (char)    c;

 char t5 =         c >             b;

 char t6 =         a >             0;

 return t1 + t2 + t3 + t4 + t5 + t6;

}

 

gcc -O1 -S -m32 ctest.c

 

ctest:

       pushl   %ebp

       movl    %esp, %ebp

       pushl   %esi

       pushl   %ebx

       movl    8(%ebp), %ebx//ebx = a

       movl    12(%ebp), %ecx // ecx = b

       movl    16(%ebp), %esi //esi = c

       cmpl    %ecx, %ebx //比较ab

       setl    %al //al = (a < b)  = t1

       testl   %ebx, %ebx //测试a的值是正数、负数还是0

       setg    %dl //dl = (a > 0) = t6

       addl    %edx, %eax //al = t1 + t6

       cmpl    %ebx, %ecx //比较ba

       setb    %dl //dl = (b <(unsigned) a) = t2

       addl    %edx, %eax //al = t1 + t6+ t2

       cmpl    %ecx, %esi //比较cb

       setg    %dl //dl = (c > b) = t5

        addl   %edx, %eax // al = t1 + t6 + t2 + t5

       cmpw    %bx, %si //ca强转成16位整数后进行比较

       setge   %dl //dl = ((short)c>=(short) a) = t3

       addl    %edx, %eax // al = t1 + t6+ t2 + t5 + t3

       movl    %esi, %edx //c的值装入edx

       cmpb    %dl, %bl //ac强转成8位整数后进行比较

       setne   %dl // dl = ((char) a !=(char) c) = t4

       addl    %edx, %eax // al = t1 + t6+ t2 + t5 + t3 + t4

       movsbl  %al,%eax //eax高位3字节用0来填充

       popl    %ebx

       popl    %esi

       popl    %ebp

       ret

你可能感兴趣的:(32位汇编语言学习笔记(6)--设置条件码)