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

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
嗨!对于逆向学习汇编语言学习笔记,我可以给你一些基本的指导。首先,汇编语言是一种低级语言,它与计算机的底层硬件密切相关。逆向工程则是通过分析和理解已编译的程序来获取程序的内部信息。 以下是一些学习汇编语言和逆向工程的建议: 1. 学习基础知识:了解计算机体系结构、寄存器、内存和指令集等基础概念是必要的。可以先阅读相关的书籍或在线教程,掌握这些基本概念。 2. 掌握汇编语言的语法和指令集:每种计算机体系结构都有自己的汇编语言语法和指令集。选择一种你感兴趣的体系结构(如x86、ARM等),并学习它的汇编语言。 3. 练习编写和调试汇编代:通过编写简单的汇编代来熟悉语法和指令集。使用调试器来单步执行代并观察寄存器和内存的变化。 4. 分析已编译程序:选择一个目标程序进行逆向分析。使用反汇编器将程序转换为汇编代,并分析代的逻辑和功能。这有助于理解程序的结构和运行过程。 5. 使用调试器进行动态分析:通过调试器来动态地执行程序,并观察程序在运行时的行为。使用断点、内存查看器和寄存器查看器等工具来分析程序的状态和数据。 6. 学习逆向工程工具和技术:了解常用的逆向工程工具和技术,如IDA Pro、OllyDbg、Ghidra等。掌握这些工具的使用可以提高你的逆向分析能力。 7. 参考优秀资源:阅读与逆向工程和汇编语言相关的书籍、论文和博客,关注相关的社区和论坛。与其他逆向工程师交流经验也是很有帮助的。 记住,逆向工程是一个需要耐心和实践的过程。持续学习和实践将帮助你提高逆向分析的技能。祝你在学习汇编语言和逆向工程的过程中取得好成果!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值