程序的机器级表示
来源:互联网 发布:员工信息管理java 编辑:程序博客网 时间:2024/05/17 23:37
操作数:CP121
立即数(Imm):
- 以$开头
- 立即数寻址
寄存器值(Reg):
- 16位寄存器的低1字节,2字节,4字节或8字节。
- ra表示寄存器a,R[ra]表示寄存器的值
- 寄存器寻址
- 内存引用(Mem)
- 根据计算出的地址来访问某个内存位置
- Mb[Addr]表示存储在以地址开始b个字节的引用
MOV类指令
- 将数据从一个位置复制到另一个位置
- 第1个是源操作数,第2个是目的操作数
- 2个操作数不能都指向内存
示例
long exchange(long *xp,long y){ long x=*xp; *xp=y; return x;}
//开始时xp存放在%rdi(存放目标索引值)//y存放在%rsi(存放源索引值)exchange: //寄存器间接寻址 movq (%rdi),%rax //由于xp是指针,所以%rdi存放的是地址。将位于该内存地址的值复制到%rax(局部变量通常存在寄存器中) movq %rsi,(%rdi) //将y的值复制到%rax的内存地址 ret //返回
CP129
加载有效地址指令:
将源操作数的地址写入目的操作数(必须是寄存器)
long t=x+4y;//假设x存放在%rdi,y存放在%rsileaq (%rdi,%rsi,4),%rax//将%rax的值设为x+4y
一元操作:操作数可以是寄存器/内存地址
二元操作:
- 第一操作数:立即数/寄存器/内存地址
- 第二操作数:寄存器/内存地址(读出后写回)
比较指令:CP136
CMP S1,S2//基于S2-S1
示例:
long arith(long x,long y){ long t1=x^y; long t2=x*48 return t2;}
xorq %rsi,%rdi//结果存在%edi(第一个参数)leaq (%rsi,%rsi,2),%rax//3*zsalq $4,%rax//左移4位,每移1次相当于乘2
跳转指令
无条件跳转:
//直接跳转jmp .L1//跳转到L1//间接跳转jmp *(%rax)//%rax存储的是
条件分支:
- 条件控制:CPU 依靠流水线工作的,比方说执行一系列操作需要 ABCDE 五个步骤。执行 B 所需的数据会在执行 A 的同时加载到寄存器中,如果程序一直是顺序的,效率会很高。
一旦遇到分支,执行完 A 下一步要执行的是 C,但是载入的数据是 B,这时候就要把流水线清空,然后重新载入 C 所需要的数据。『分支预测』这一技术来解决(分支预测有概率可能猜错)。 - 条件传送:
- 先计算出表达式的值
- 只有当表达式的值容易计算时才会采用条件传送
long absdiff(long x, long y){ long result; if (x > y) result = x-y; else result = y-x; return result;}
反汇编
long result; int ntest = x <= y; if (ntest) goto Else; result = x-y; goto Done;Else: result = y-x;Done: return result;
汇编
movq %rsi, %rax # x subq %rdi, %rax # result = y-x movq %rdi, %rdx subq %rsi, %rdx # eval = y-x cmpq %rsi, %rdi # x:y cmovge %rdx, %rax # %rax存储返回值 ret
循环:
- 组合条件测试和跳转产生循环的效果
- do-while
loop: 循环体; t=循环条件; if(t) goto loop;
例如
long pcount_goto(long n){ long result = 1;loop: result *=n; n=n-1; if (n>1) goto loop; return result;}
pcount_goto: movl $1, %eax # result = 1.L2: # loop: imulq %rdi, %rax # %rdi=n,%rax=result subq $1, %rdi cmpq $1, %rdi jg .L2 # 大于跳转 rep; ret
- while
guarded-do(较高优化等级):初始条件成立时,进入do-while循环( Do-While 语句执行起来更快,更符合 CPU 的运算模型)
t=循环条件;if(!t) goto done;loop: 循环体; t=循环条件; if(t) goto loop;done:
- for循环
初始表达式;for (Init; Test; Update) BodyInit;while (Test) { Body Update;}
switch
跳转表
- 是1个数组
- 数组元素为代码段,开关索引值等于某个i时进行跳转
- 开关数量比较多且值的跨度比较小时使用
CP160 void* jt[7]是跳转表,元素(例如&&loc_A)代表代码段的地址。为了使下标从尽可能小的地方开始,将n-100作为开关索引值。
过程:
对于每个过程调用来说,都会在栈中分配一个帧 Frames。每一帧里需要包含:返回信息,本地存储(如果需要)临时空间
- 传递控制:调用时将PC设置成被调用函数的起始地址;返回时将PC设置成原函数的下1条指令。
传递数据:
- 参数:不超过6个通过寄存器传递(图3-28)
;超过6个通过栈传递 - 返回值:通过寄存器%rax传递
- 参数:不超过6个通过寄存器传递(图3-28)
分配释放内存:CP170局部变量有时需要存放在内存中
long mult2(long a, long b){ long s = a * b; return s;}//汇编0000000000400550 <mult2>: # a 在 %rdi 中,b 在 %rsi 中 mov %rdi, %rax # 得到 a 的值 imul %rsi, %rax # a * b # s 在 %rax 中 retq # 返回
void multstore (long x, long, y, long *dest){ long t = mult2(x, y); *dest = t;}0000000000400540 <multstore>:# x 在 %rdi 中,y 在 %rsi 中,dest 在 %rdx 中 push %rbx # CP173被调用者保护寄存器 mov %rdx, %rbx # 保存 dest# 程序计数器%rip指向mult2的起始地址 callq 400550 <mult2> # 调用 mult2(x, y)# 返回结果在 %rax 中 mov %rax, (%rbx) # 保存到 dest指向的地址 pop %rbx # 恢复%rbx的原值 retq # 返回
阅读全文
0 0
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序的机器级表示
- 程序机器级表示
- chap3: 程序的机器级表示
- 程序的机器级表示(一)
- 程序的机器级表示(二)
- 第三章 程序的机器级表示
- Java设计模式-工厂方法模式
- 动态任务
- GeoWave安装部署实践
- 【小小决斗】我看你不顺眼很久了,快来和我一决高下!
- ACM推荐网站
- 程序的机器级表示
- Myeclipse 2015 stable 1.0 完美破解方法
- 《庄子》阅读感想-逍遥游
- Solr整合Ansj中文分词器
- 模仿新闻头条,上面滑动,下面ViewPager跟随滑动
- Java内存区域与内存溢出异常
- undefined reference to `history_get'
- hdu541(树状数组)
- 前序中序后序