汇编语言简介

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

子程序结构(续)
子程序的嵌套和递归 主程序 … call proc_a … 子程序A A proc_a … call proc_b … ret 子程序b proc_b … ret
数组
数组的定义
数组(续)
数组元素的访问
– array1 db 5, 4, 3, 2, 1 ; array of bytes – array2 dw 5, 4, 3, 2, 1 ; array of words
子程序结构(续)
参数传递
– 参数传递方式
通过寄存器传递参数 如过程和调用程序在同一源文件(程序模块)中,过程可以直接访问模块中 的变量 通过地址表传递参数地址 通过堆栈传送参数或参数地址
– 参数传递顺序
Pascal从左向右压入参数 C从右向左压入参数
– 清除堆栈上传递的参数
Pascal由callee函数清除参数 C由caller清除参数
Intel格式 mov al, byte ptr val
AT&T格式 ljump $section, $offset lcall $section, $offset lret $stack_adjust
数据存储
可执行程序在内存中的结构
– .text 代码段
存放代码
– .data 数据段
存放数据
子程序结构
基于堆栈的子程序结构 堆栈对齐
– IA-32中堆栈是4字节对齐,IA-64中可以是8字节对齐 – 压入堆栈的数据必须对齐,byte数据在压入堆栈之前必须扩展为四字节
堆栈生长方向
– IA-32中源自文库栈向下生长,压入数据堆栈指针减少,弹出数据堆栈指针增加 IA-32
堆栈指针
– IA-32中堆栈指针指向栈顶第一个可用地址
– .rodata 只读数据段
存放只读数据,如C中的字符串和其它常量 C
– .bss 未初始化数据段
存放未初始化的全局或静态数据,这些内存必须初始化为0
数据对齐
– 系统存储结构有关,页对齐
段起始地址要求页对齐,便于缺页处理
– 减少Cache miss ,Cache line 对齐
结构体常要求cache line对齐,提高访问效率
汇编语言简介
OSLAB
主要内容
汇编语言概述 数据存储 条件控制 子程序结构 数组 实例
汇编语言概述
汇编语言
– 优点
能够直接访问与硬件相关的存储器或 I/O 端口; 能够不受编译器的限制,对生成的二进制代码进行完全的控制; 能够对关键代码进行更准确的控制,避免因线程共同访问或者 硬件设备共享引起的死锁; 能够根据特定的应用对代码做最佳的优化,提高运行速度; 能够最大限度地发挥硬件的功能.
– 减少内存读写次数,字对齐
普通变量要求字对齐,减少内存读写次数
条件控制
高级语言的条件控制
– while, if
汇编语言的条件控制
– 会将条件判断的结果放在FLAGS寄存器中,以 便根据结果来做出相应的条件控制 – 条件控制指令的分类
比较指令 转移指令 循环控制指令
条件控制(续)
比较指令
实例
AT&T格式的"hello world"程序
#hello.s .data # 数据段声明 msg : .string "Hello, world!\\n" # 要输出的字符串 len = . - msg # 字串长度 .text # 代码段声明 .global _start # 指定入口函数 _start: # 在屏幕上显示一个字符串 movl $len, %edx # 参数三:字符串长度 movl $msg, %ecx # 参数二:要显示的字符串 movl $1, %ebx # 参数一:文件描述符(stdout) movl $4, %eax # 系统调用号(sys_write) int $0x80 # 调用内核功能 # 退出程序 movl $0,%ebx # 参数一:退出代码 movl $1,%eax # 系统调用号(sys_exit) int $0x80 # 调用内核功能
– C方式的优点
可变参数列表容易实现 汇编语言编写C函数
– 简化了汇编语言子程序的复杂性,考虑需要使用可变参数的汇编子程序
子程序结构(续)
返回值传递方式
– 简单类型,指针类型,%eax寄存器(小于32 位)或者%eax和%edx(大于32位小于64位) – 结构体类型,函数原型中返回类型作为形式参 数列表的一部分;struct my f(int k)将转化为 void f(struct my *p, int k); 实际调用时将返回对 象的赋值目标地址作为参数
Intel格式 jmp far section:offset call far section:offset ret far stack_adjust AT&T格式 movl -4(%ebp), %eax Intel格式 mov eax, [ebp - 4] AT&T格式 pushl %eax AT&T格式 pushl $1 AT&T格式 addl $1, %eax AT&T格式 movb val, %al Intel格式 push eax Intel格式 push 1 Intel格式 add eax, 1
C语言函数结构
– 活动记录
函数参数,返回地址,局部变量
– 变量上下文环境
C语言两层函数结构,不是全局变量,便是局部变量 全局变量在数据段,局部变量位于堆栈
子程序结构(续)
堆栈操作及图示
– 在调用子程序之前需要进行堆栈的保存 – 子程序调用之后需要对堆栈进行恢复 – 利用push/pop/pusha/pushad/popa/popad指令对堆栈 进行操作
– 存储器操作数
直接寻址方式 寄存器间接寻址方式
– 立即数
操作数直接放在指令中 (addl $1, %eax )
– 暗含操作数
自增/自减运算中的操作数1
汇编语言概述(续)
AT&T汇编与Intel汇编的区别
– – – – – 寄存器名的不同 立即数形式的不同 源操作数和目标操作数的位置的不同 操作数的字长决定方式的不同 远程转移指令和远程子调用指令的操 作码的不同 – 内存操作数寻址方式的不同
– cmp vleft, vright
转移指令
– 无条件转移指令
jmp opr
– 条件转移指令
the zero (ZF) flag, the overflow (OF) flag and the sign (SF) flag JZ branches only if ZF is set JNZ branches only if ZF is unset JO branches only if OF is set JNO branches only if OF is unset JS branches only if SF is set JNS branches only if SF is unset JC branches only if CF is set JNC branches only if CF is unset JP branches only if PF is set JNP branches only if PF is unset

– 缺点
编写的代码非常难懂,不好维护; 很容易产生 bug,难于调试; 只能针对特定的体系结构和处理器进行优化; 开发效率很低,时间长且单调.
汇编语言概述(续)
汇编指令的操作数
– 寄存器操作数
操作数在寄存器中 (pushl %eax )
一些基本的汇编指令
– – – – – mov dest, src add opr1, opr2 sub opr1, opr2 inc opr dec opr
条件控制(续)
循环控制指令
– loop
递减ecx,如果ecx不等于0,跳转到指定label
– loope, loopne
递减ecx,如果ecx不等于0,跳转到指定label 递减ecx,如果ecx等于0,跳转到指定label
– loopz, loopnz
递减ecx,如果zf等于1,跳转到指定label 递减ecx,如果zf不等于1,跳转到指定label
相关文档
最新文档