32位汇编语言学习笔记(6)--设置条件码
2014-11-22 15:59
579 查看
条件码保存在条件码寄存器中,用于描述算术和最近逻辑操作的属性。最常用的条件码有:
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,等于0,D=ZF。
setz D,与sete相同。
setne D,不等于0,D=~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)
//比较a和b
setl
%al //如果a<b,al会设置成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 //比较a和b
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 //比较b和a
setb
%dl //dl = (b <(unsigned) a) = t2
addl
%edx, %eax //al = t1 + t6+ t2
cmpl
%ecx, %esi //比较c和b
setg
%dl //dl = (c > b) = t5
addl %edx, %eax // al = t1 + t6 + t2 + t5
cmpw
%bx, %si //把c和a强转成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 //把a和c强转成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
条件码保存在条件码寄存器中,用于描述算术和最近逻辑操作的属性。最常用的条件码有:
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,等于0,D=ZF。
setz D,与sete相同。
setne D,不等于0,D=~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)
//比较a和b
setl
%al //如果a<b,al会设置成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 //比较a和b
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 //比较b和a
setb
%dl //dl = (b <(unsigned) a) = t2
addl
%edx, %eax //al = t1 + t6+ t2
cmpl
%ecx, %esi //比较c和b
setg
%dl //dl = (c > b) = t5
addl %edx, %eax // al = t1 + t6 + t2 + t5
cmpw
%bx, %si //把c和a强转成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 //把a和c强转成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位汇编语言学习笔记(11)--条件传送指令
- windows下32位汇编语言学习笔记 第十章 内存管理部分 1
- 32位汇编语言学习笔记(4)--移位操作
- 32位汇编语言学习笔记(10)--分析for循环的汇编代码
- 32位汇编语言学习笔记(9)--分析while循环的汇编代码
- 32位汇编语言学习笔记(20)--栈破坏检测
- windows下32位汇编语言学习笔记 第十章 内存管理部分 2
- 32位汇编语言学习笔记(13)--函数的调用
- 32位汇编语言学习笔记(17)--结构体
- windows下32位汇编语言学习笔记
- 32位汇编语言学习笔记(15)--定长数组
- windows下32位汇编语言学习笔记
- windows下32位汇编语言学习笔记
- 32位汇编语言学习笔记(7)--跳转指令
- 32位汇编语言学习笔记(18)--联合
- windows下32位汇编语言学习笔记 第四章 第一个窗口程序 (windows的消息机制)
- 32位汇编语言学习笔记(3)--leal和算术运算指令
- 32位汇编语言学习笔记(5)--特殊的算术操作
- 32位汇编语言学习笔记(1)--简单示例
- 32位汇编语言学习笔记(16)--变长数组