Linux下的汇编与Windows汇编最大的不同就是第一个操作数(2)

2020-02-21 23:13

图4:特别的算术操作

给个例子和其相应的反汇编代码练习一下。 #include intmain() {

inta=6,b=3;

unsignedintc=10,d=2; intans1=a/b;

unsignedintans2=c*d; return0; }

0x08048394: lea0x4(%esp),ìx 0x08048398: and$0xfffffff0,%esp 0x0804839b: pushl-0x4(ìx) 0x0804839e: push?p 0x0804839f: mov%esp,?p 0x080483a1: pushìx

0x080483a2: sub$0x28,%esp

0x080483a5: movl$0x6,-0x8(?p) 0x080483ac: movl$0x3,-0xc(?p) 0x080483b3: movl$0xa,-0x10(?p) 0x080483ba: movl$0x2,-0x14(?p) 0x080483c1: mov-0x8(?p),êx 0x080483c4: movêx,-0x2c(?p) 0x080483c7: mov-0x2c(?p),íx 0x080483ca: movíx,êx 0x080483cc: sar$0x1f,íx 0x080483cf: idivl-0xc(?p)

0x080483d2: movêx,-0x18(?p) 0x080483d5: mov-0x10(?p),êx 0x080483d8: imul-0x14(?p),êx 0x080483dc: movêx,-0x1c(?p) 0x080483df: mov$0x0,êx 0x080483e4: add$0x28,%esp 0x080483e7: popìx 0x080483e8: pop?p

0x080483e9: lea-0x4(ìx),%esp 0x080483ec: ret

2、操纵结构

CF:进位标志。最近的操作使最高位产生了进位,它可用来检查无符号操作数的

溢出。

ZF:零标志。最近的操作得出的结果为0。

SF:符号标志。最近的操作得到的结果为负数。

OF:溢出标志。最近的操作导致一个二进制补码溢出——正溢出或负溢出。 整型变量a、b和t,用add指令完成等价于C表达式t=a+b的功能。会依照下面的表达式来设置条件码:

CF:(unsignedt)<(unsigneda)无符号溢出 ZF:(t==0) 零

SF:(t<0) 负数 OF:(a<0==b<0)&&(t<0!=a<0)有符号溢出

lea指令不改变任何条件码,因为它是用来进行地址计算的。 指令 基于 描述 cmpbS2,S1 S1–S2 比较字节 testbS2,S1 S1&S2 测试字节 cmpwS2,S1 S1–S2 比较字 testwS2,S1 S1&S2 测试字 cmplS2,S1 S1–S2 比较双字 testlS2,S1 S1&S2 测试双字 图5:比较指令 cmpb、cmpw、cmpl指令依照它们的两个操作数之差来设置条件码。

testb、testw、testl指令会依照它们的两个操作数的与(AND)来设置零标志和负数标志。 指令 同义名 效果 设置条件 seteD setz D←ZF 相等/零 setneD setnz D←~ZF 不等/非零 setsD D←SF 负数 setnsD D←~SF 非负数 setgD setnle D←~(SF^|OF)&~ZF 大于(有符号>) setgeD setnl D←~(SF^|OF) 大于等于(有符号>=) setlD setnge D←SF^|OF 小于(有符号<) setleD setng D←(SF^OF)|ZF 小于等于(有符号<=) setaD setnbe D←~CF&~ZF 超过(无符号) setaeD segnb D←~CF 超过或相等(无符号>=) setbD setnae D←CF 低于〔无符号<〕 setbeD setna D←CF|ZF 低于或相等(无符号<=) 图6:sett指令 每条指令依照条件码的某个组合,将一个字节设置为0或者1。有些指令有“同义名”,也确实是,同一条机器指令有别的名字 结合上面的说明练习一下。 #include

charctest(inta,intb,intc) {

chart1=a

chart2=b<(unsigned)a;

chart3=(short)c>=(short)a; chart4=(char)a!=(char)c; chart5=c>b;

chart6=a>0;

intsum=t1+t2+t3+t4+t5+t6; returnsum; }

intmain() {

intx=5,y=6,z=7;

intans=ctest(x,y,z); printf(“%d\\n”,ans); return0; }

(gdb)disasctest

0x080483c4: 0x080483c5: 0x080483c7: 0x080483ca: 0x080483cd: 0x080483d0: 0x080483d3: 0x080483d6: 0x080483d9: 0x080483dc: 0x080483de: 0x080483e1: 0x080483e4: 0x080483e7: 0x080483e9: 0x080483ec: 0x080483ef: 0x080483f2: 0x080483f5: 0x080483f8: 0x080483fa: 0x080483fd: 0x080483ff: 0x08048402: 0x08048405: 0x08048408: 0x0804840b: 0x0804840e: 0x08048411: 0x08048415: 0x08048418: 0x0804841b: push?p mov%esp,?p sub$0x10,%esp mov0x8(?p),êx cmp0xc(?p),êx setl%al

mov%al,-0x1(?p) mov0xc(?p),íx mov0x8(?p),êx cmpêx,íx setb%al

mov%al,-0x2(?p) mov0x10(?p),êx movêx,íx

mov0x8(?p),êx cmp%ax,%dx setge%al

mov%al,-0x3(?p) mov0x8(?p),êx movêx,íx

mov0x10(?p),êx cmp%al,%dl setne%al

mov%al,-0x4(?p) mov0x10(?p),êx cmp0xc(?p),êx setg%al

mov%al,-0x5(?p) cmpl$0x0,0x8(?p) setg%al

mov%al,-0x6(?p) movsbl-0x1(?p),íx

0x0804841f: 0x08048423: 0x08048425: 0x08048429: 0x0804842b: 0x0804842f: 0x08048431: 0x08048435: 0x08048437: 0x0804843b: 0x0804843e: 0x08048441: 0x08048444: 0x08048445: 指令 同义名 jmpLabel jmp*Operand jeLabel jz jneLabel jnz jsLabel jnsLabel jgLabel jnle jgeLabel jnl jlLabel jnge jleLabel jng jaLabel jnbe jaeLabel jnb jbLabel jnae jbeLabel jna movsbl-0x2(?p),êx

addêx,íx

movsbl-0x3(?p),êx addêx,íx

movsbl-0x4(?p),êx addêx,íx

movsbl-0x5(?p),êx addêx,íx

movsbl-0x6(?p),êx lea(íx,êx,1),êx movêx,-0xc(?p) mov-0xc(?p),êx leave ret 跳转条件 描述 1 直截了当跳转 1 间接跳转 ZF 相等/零 ~ZF 不相等/非零 SF 负数 ~SF 非负数 ~(SF^OF)&~ZF 大于(有符号>) ~(SF^OF) 大于或等于(有符号>=) SF^OF 小于(有符号<) (SF^OF)|OF 小于或等于(有符号<=) ~CF&~ZF 超过(无符号>) ~CF 超过或相等(无符号>=) CF 低于(无符号<) CF|ZF 低于或相等(无符号<=) 图7:条件跳转指令

jmp指令是无条件跳转,它能够是直截了当跳转,即跳转目标是作为指令的一部分编码的,也能够是间接跳转,即跳转目标是从寄存器或存储器位置中读出的。看下面的两条指令:

jmp*êx用寄存器êx中的值作为跳转目标。

jmp*(êx)以êx中的值作为读地址,从存储器中读出跳转目标。

跳转指令有几种不同的编码,然而最常用的一些事PC相关的,也确实是,它们会将目标指令的地址与紧跟在跳转指令后面那条指令的地址之间的差作为编码。这些地址偏移量能够编码为【一】二或四个字节。第二种编码方法是给出“绝对”地址,用四个字节直截了当指定目标。

下面给出具体的例子进行一些分析,动手实践是必须要的,在计算机这一块中编程能力依旧第一位的,那个也关系到自己以后职业的定位和进展。大伙勤加练习,我也正在努力中。

C中的if-else语句的通用形式是如此的:

if(test-expr)

thenstatement else

else-statement

那个地方test-expr是一个整数表达式,它的取值为0〔解释为“假”〕或者为非0〔解释为“真”〕,两个分支语句〔then-statement和else-statement〕只会执行一个。

#include #include usingnamespacestd; intabsdiff(intx,inty) {

if(x

returnx-y; }

intmain() {

intm=5,n=6; intans=0;

ans=absdiff(m,n); printf(“%d\\n”,ans); return0; }

0x080485a4<_Z7absdiffii+0>: 0x080485a5<_Z7absdiffii+1>: 0x080485a7<_Z7absdiffii+3>: 0x080485aa<_Z7absdiffii+6>: 0x080485ad<_Z7absdiffii+9>: 0x080485b0<_Z7absdiffii+12>: 0x080485b2<_Z7absdiffii+14>: 0x080485b5<_Z7absdiffii+17>: 0x080485b8<_Z7absdiffii+20>: 0x080485ba<_Z7absdiffii+22>: 0x080485bc<_Z7absdiffii+24>: 0x080485bf<_Z7absdiffii+27>: 0x080485c1<_Z7absdiffii+29>: 0x080485c4<_Z7absdiffii+32>: 0x080485c7<_Z7absdiffii+35>: 0x080485c9<_Z7absdiffii+37>: 0x080485cb<_Z7absdiffii+39>: 0x080485ce<_Z7absdiffii+42>: 0x080485d1<_Z7absdiffii+45>: push?p mov%esp,?p sub$0x4,%esp

mov0x8(?p),êx cmp0xc(?p),êx

jge0x80485c1<_Z7absdiffii+29> mov0x8(?p),íx mov0xc(?p),êx movêx,ìx subíx,ìx

movìx,-0x4(?p)

jmp0x80485ce<_Z7absdiffii+42> mov0xc(?p),íx mov0x8(?p),êx movêx,ìx subíx,ìx

movìx,-0x4(?p) mov-0x4(?p),êx leave


Linux下的汇编与Windows汇编最大的不同就是第一个操作数(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:《物业设备设施管理》形成性考核册参考答案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: