第4章汇编语言_第1页
第4章汇编语言_第2页
第4章汇编语言_第3页
第4章汇编语言_第4页
第4章汇编语言_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2020 4 6 80 x86汇编语言程序设计 第4章汇编语言程序格式 讲授要点 常用伪指令与操作符 汇编语言源程序的基本框架 汇编语言程序的开发过程以及程序的调试方法 2020 4 6 80 x86汇编语言程序设计 4 1地址计数器 汇编器在将源程序转换为目标程序的过程中 每汇编一个段 都需要跟踪其中代码或数据的偏移地址 这就是地址计数器 地址计数器的值表示当前偏移地址 在缺省情况下 段的偏移地址从0开始 例如 下列指令序列 0 movbl al 机器码为2字节2 andbl 0fh 机器码为3字节5 movbh al 机器码为2字节7 shrbh 4 机器码为3字节A 若该指令序列出现在段的开始 那么 在汇编相应指令时 地址计数器的值如左侧所示 例如 第1条MOV指令始于偏移地址0 由于该MOV指令是2字节 故下一条指令始于偏移地址2 等等 2020 4 6 80 x86汇编语言程序设计 4 2汇编语言语句 1 语句格式 1 语句的书写形式 名字助记符操作数 注释 2 MASM对语句格式的要求 大小写无关 每条语句必须占 行 但可以使用续行符 为了提高可读性 应该使各个域对齐 2 常数与数值表达式整数 包括二进制 十进制 八进制或十六进制表示的整数 字符与字符串 必须用单引号或双引号括起来 数值表达式 2020 4 6 80 x86汇编语言程序设计 3 变量 标号与地址表达式变量与标号的3种属性 段地址 偏移地址 类型 变量的类型包括BYTE 字节 WORD 字 DWORD 双字 等 标号的类型包括NEAR和FAR 地址表达式 地址表达式的基本形式为 变量名或标号名 常数其类型由相应的变量或标号确定 两个地址表达式的差表示两个地址之间的距离 字节数 两个地址必须在同一个段内 注意 不能将两个地址表达式相加 是一个特殊的地址表达式 表示当前地址 即地址计数器的当前值 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 1 处理器选择伪指令在缺省方式下 MASM只承认8086指令 为了使用更高的CPU指令 必须使用处理器选择伪指令 主要包括 8086 286 286P 386 386P 486 486P 586 586P 686 686P分别表示其后面的代码使用相应CPU的指令 其中 结尾的 P 表示使用特权指令 若使用32位CPU新增指令以及寄存器或内存寻址方式 则至少要用 386伪指令 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 2 段定义伪指令段定义由SEGMENT与ENDS伪指令实现 基本形式如下 段名SEGMENTSTACKUSE16段名ENDS其中 STACK仅用于堆栈段 USE16指出使用16位段 在实模式下 只能使用16位段 而32位段只能用于保护模式程序 在实模式下 如果要使用32位指令 还必须在段定义时给出USE16 段名作为操作数出现在指令中时 MASM将其视为立即数 表示段地址 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 3 符号定义伪指令基本形式 符号名EQU表达式符号名 常数表达式功能 给表达式指定一个等价的符号名 说明 1 后的表达式只能是常数 对于字符或字符串 汇编时按整数处理 例如 COUNT 20MOVCX COUNT 等价于MOVCX 20 2 EQU后的表达式可以是数值 字符串 寄存器名 指令助记符等 3 EQU不能重复定义 而 可重复定义 其作用域从定义点到重新定义之前 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 4 变量定义伪指令变量定义伪指令用来为数据分配内存空间 并设置相应内存单元的初始值 形式 变量名变量定义符操作数 操作数其中 变量名是一个符号地址 表示其后操作数的首地址 变量名为可选项 给出变量名只是为了按名存取其对应的内存单元 变量定义符主要包括下列几种 DB DefineByte 定义字节 后面的每个操作数占1个字节 DW DefineWord 定义字 后面的每个操作数占1个字 DD DefineDword 定义双字 后面的每个操作数占2个字 操作数可以是常数 用EQU或 定义的符号常量 表达式 和DUP子句等 其中 表示只保留内存空间 未定义初始值 DUP子句的格式为 重复次数DUP 操作数 操作数 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 说明 1 变量可以定义在任何段 包括代码段 但一般定义在数据段 2 用DW DD DQ DF DT定义的数据在内存按 低字节在低地址 的方式存放 例如 S1DB AB 等价于S1DB41H 42HS2DW AB 等价于S2DW4142H 3 当DW与DD后的操作数是地址表达式时 分别表示其16位偏移地址和32位分段地址 段地址在高字 偏移地址在低字 例如 XDB10DUP ADDR1DWX ADDR1的内容 字 为变量X的偏移地址ADDR2DDX ADDR2的高字为X的段地址 低字为X的偏移地址 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 4 MASM是强类型的 变量在定义后 其类型便被确定 使用时要注意类型匹配 例如 OP1DB OP2DW 下列两条指令执行不同类型的操作 MOVOP1 1 0 字节操作指令 将0作为1个字节送到地址OP1 1MOVOP2 2 0 字操作指令 将0作为1个字送到地址OP2 2然而 下列两条指令是错误的 MOVOP1 AX 类型不匹配MOVOP2 AL 类型不匹配若希望进行与变量类型不一致的操作 例如 对字变量实施字节操作 如何处理 可以采用下面介绍的LABEL伪指令或类型操作符PTR等 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 5 LABEL基本形式 名字LABEL类型功能 将名字作为一个符号地址 指定其类型 地址由所在位置确定 然而 并不为名字分配内存空间 说明 当类型是BYTE WORD DWORD时 名字作为相应类型的变量 当类型是NEAR或FAR时 名字作为相应类型的标号 例 定义地址相同 类型不同的两个变量 balabelbytewadw50dup 将100个字节的数组首地址赋予两个不同类型的变量 字节类型变量BA与字类型变量WA 尽管WA 2与BA 2指向同一内存地址 但下列两条指令的操作类型不同 movwa 2 0 将0作为1个字送到地址WA 2movba 2 0 将0作为1个字节送到地址BA 2 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 6 ASSUME基本形式 ASSUME段寄存器名 段名 段寄存器名 段名功能 明确指出段与段寄存器的缺省对应关系 即告诉MASM某个段的段地址在哪个段寄存器里 这样 汇编器会根据变量所在的段 必要时自动插入段超越前缀 例如 下列伪指令ASSUMECS CSEG DS DSEG ES ESEG SS SSEG指出CSEG DSEG ESEG和SSEG分别为代码段 数据段 附加段和堆栈段 通常 访问的数据在DS所指的数据段或SS所指的堆栈段 而所有的代码引用 如转移等 相对于当前代码段 那么 汇编器如何知道哪个段是代码段 哪个是数据段呢 实际上 数据段之所以成为数据段 是由于DS指向它 由于程序运行时可以改变DS的值 使得任何段都可以成为数据段 因此 当程序定义一个段后 需要告诉汇编器该段的段地址在哪个段寄存器中 ASSUME就提供这种信息 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 6 源程序结束伪指令基本形式 END地址功能 表示汇编语言源程序到此结束 对END之后的语句不再进行汇编 可选的地址指出程序执行的起始点 通常是标号或过程名 若程序包含多个源文件 则每个源文件的最后必须有一条END语句 但只有主模块文件可以指出执行的起始地址 2020 4 6 80 x86汇编语言程序设计 4 3基本伪指令 7 ORG通常 段中的数据或指令是按顺序一个接着一个存放的 ORG可以控制数据或代码的偏移地址 形式为 ORG常数表达式功能 设置其后数据或代码的起始偏移地址为n 设常数表达式的值为n 也就是将地址计数器的值置为n 例 已知下列数据段 指出变量V1 V2的偏移地址 datasegmentorg200hv1dw1 2 v1的偏移地址为200horg 10h 跳过10h个字节v2db v2的偏移地址为214hdataends 2020 4 6 80 x86汇编语言程序设计 4 4操作符 1 地址操作符地址操作符的返回值都是数值 相当于立即数 是汇编时由MASM自动计算的 1 SEG形式 SEG地址表达式功能 返回地址表达式的段地址 作为立即数使用 汇编时求值 2 OFFSET形式 OFFSET地址表达式功能 返回地址表达式的偏移地址 作为立即数使用 汇编时求值 2020 4 6 80 x86汇编语言程序设计 4 4操作符 3 TYPE SIZEOF和LENGTHOF形式 TYPE变量SIZEOF变量LENGTHOF变量功能 TYPE返回一个常数 表示变量的类型 对于BYTE WORD DWORD 类型 分别返回1 2 4 LENGTHOF返回直接分配给指定变量的元素个数 SIZEOF返回直接分配给指定变量的字节数 2020 4 6 80 x86汇编语言程序设计 4 4操作符 2 类型操作符 1 PTR形式 类型PTR内存操作数或标号功能 返回一个指定类型的内存操作数或标号 而地址不变 对于内存操作数 类型包括BYTE WORD DWORD等 对于标号 类型包括NEAR和FAR 说明 PTR只是临时改变操作数的类型 类似于C语言的强制类型转换 2 THIS形式 THIS类型功能 返回一个指定类型的内存操作数或标号 地址由所在位置确定 即地址计数器的当前值 2020 4 6 80 x86汇编语言程序设计 4 4操作符 例 设有如下定义 WordVardw10dup 欲将WordVar的第0个字节置为1 如何处理 方法1 用PTR操作符 WordVardw10dup movbyteptrWordVar 1方法2 用THIS与EQU ByteVarequthisbyteWordVardw10dup movByteVar 1 2020 4 6 80 x86汇编语言程序设计 4 5汇编语言源程序结构 1 源程序的一般结构源程序由若干个代码段 数据段 附加段和堆栈段组成 段之间的顺序可以随意安排 通常需要一个代码段 一个数据段和一个堆栈段 有时可包含一个附加段 2020 4 6 80 x86汇编语言程序设计 2 源程序的基本框架 386 若干符号定义dsegsegmentuse16 数据定义 DB DW DD dsegendsesegsegmentuse16 数据定义 DB DW DD esegendsssegsegmentstackuse16dw512dup ssegends csegsegmentuse16assumecs cseg ds dseg es eseg ss ssegstart movax dsegmovds axmovax esegmoves ax 指令序列movah 4chint21h 程序退出 返回DOScsegendsendstart 2020 4 6 80 x86汇编语言程序设计 3 说明 1 为什么要用ASSUME语句 每当MASM遇到一个变量名时 首先检查看哪个段定义了该变量 例如 遇到指令MOVTABLE 0时 MASM首先确定TABLE所在的段 然后 看该段是否已在ASSUME语句中声明 若未声明 则显示错误信息 不能访问该变量 若该段不对应于DS 假设对应于ES 则MASM产生一个段超越前缀ES 即MOVES TABLE 0实际上 ASSUME的功能也仅此而已 此外 段超越前缀总是超越ASSUME的定义 注意 ASSUME只是告诉汇编器段寄存器指向哪个段 并不设置段寄存器的值 2 设置段寄存器的初值 CS与IP的初值不能在程序中显式设置 由系统自动设置为END后指定的起始地址 DS ES的初值必须在程序中设置 SS与SP的初值可在程序中显式设置 然而 若堆栈段定义时给出了属性STACK 则由系统自动设置 2020 4 6 80 x86汇编语言程序设计 4 6汇编语言程序的开发 1 开发过程源程序的编辑 源程序的汇编 目标文件的连接 可执行文件的运行 可执行文件的调试 2 汇编器MLML可以自动调用LINK 依次进行汇编和连接 常用命令如下 ML Zi源文件名3 调试器CodeViewCodeView可以调试32位程序 Debug只能调试16位程序 2020 4 6 80 x86汇编

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论