Download presentation
Presentation is loading. Please wait.
1
IBM-PC 汇编语言程序设计 教师:袁南儿
2
目 录 第一章 基础知识简介 第二章 IBM PC 计算机组织 第三章 IBM PC机的指令系统和寻址方式 第四章 汇编语言程序格式
目 录 第一章 基础知识简介 第二章 IBM PC 计算机组织 第三章 IBM PC机的指令系统和寻址方式 第四章 汇编语言程序格式 第五章 循环与分支程序设计 第六章 子程序结构 第七章 高级汇编语言技术 第八章 输入/输出程序设计 第九章 BIOS和DOS中断 第十章 发声系统的程序设计
3
第四章 汇编语言程序格式 4.1汇编程序功能 汇编语言程序的建立及汇编过程: EXE程序还需经DEBUG的调试 编辑程序 PROGR
第四章 汇编语言程序格式 4.1汇编程序功能 汇编语言程序的建立及汇编过程: 编辑程序 PROGR .ASM文件 汇编程序 连接程序 .OBJ 文件 .EXE 文件 EDIT.exe LINK.exe MASM.exe EXE程序还需经DEBUG的调试
4
在计算机上运行汇编语言程序的步骤是: 1) 用编辑程序建立源文件; filename.ASM 用MASM程序把ASM文件转换成OBJ文件; 2) 3) 用LINK程序把OBJ文件转换成EXE文件; 4)经DEBUG的调试 5)用DOS命令直接键入文件名就可以执行该程序。
5
汇编程序 汇编程序作用 ① 检查源代码语句,语法的错误,给出指示 连接程序
源程序:由一系列指令系统所提供的基本语句构成,还有标号、表达式、宏指令组成 。 汇编程序作用 ① 检查源代码语句,语法的错误,给出指示 ② 确定变量、标号的段内地址,计算表达式的值,生成符号表 ③ 展开宏指令 ④ 生成目标程序,但段末定位,称可浮动的目标程序 连接程序 确定段地址,成为装入内存可执行的二进制文件(exe)。 以下先介绍构成源代码程序的伪操作。
6
伪操作 又称伪指令: 是在汇编期间由汇编程序处理的操作 不是机器指令,不是程序运行时执行的
主要完成数据定义、分配内存、程序框架定义、指示程序结束等功能 相似于高级语言的指示性语句
7
8086的伪指令 有60多条,常用的有: ① 与汇编程序格式有关(框架) 段定义 段假设 过程定义 程序结束 ② 数据定义 ③ 符号定义
① 与汇编程序格式有关(框架) 段定义 段假设 过程定义 程序结束 ② 数据定义 ③ 符号定义 ④ 结构定义 ⑤ 常用操作符
8
伪指令的格式 [名字] [ 伪操作命令] [操作数] [;注释] ①名字后不能有冒号,这是与指令语句的突出区别
[名字] [ 伪操作命令] [操作数] [;注释] ①名字后不能有冒号,这是与指令语句的突出区别 ②名字可以是变量名,过程名、段名、组名、常量名、符号 ③名字是由程序员创造的一些名称,有一系列字母、数字、下划线 4)伪操作命令不会产生或机器码,不是指令运行时执行。是在汇编过程中由汇编程序使用执行。
9
(一) 完整段定义伪操作(程序格式) … 段定义伪操作的格式如下: segment_ name SEGMENT
segment _ name ENDS 段名 SEGMENT : 段名 ENDS SEGMENT ENDS总是成对使用,它将源程序分成几个段 ,段名是由程序员定。
10
… … 段寄存器:是CS,DS,ES、SS之一; 段名:是由SEGMENT定义 程序格式举例:
data_seg1 segment ;define data segment … data_seg1 ends data_seg2 segment ;define extra segment … data_seg2 ends
11
明确段和段寄存器的关系 在代码段中表明段名和段寄存器的对应关系 ASSUME assignment,……, assignment
段寄存器名:段名,段寄存器名:段名 分配后,还要将段名送入相应的段寄存器: 注意:段名是段地址,是一个数据,不能直接送入段寄存器。
12
… code_seg segment; define code
assume cs:code_seg,ds:data_seg1,es:data_seg2 start: mov ax,data_seg ;data segment addr mov ds,ax ;into DS register mov ax,data_seg ;extra segment addr mov es,ax ;into ES register … code_seg ends ;end of segment end start
13
代码段的程序结构(一) : cods segment main proc far assume cs:cods,ds:data1
es:data2 Start: PUSH DS MOV AX,0 PUSH AX MOV AX, DATA1 MOV DS, AX MOV AX, DATA2 MOV ES, AX * RET ; main endp cods ends end start :
14
代码段的程序结构(二) : cods segment main proc far assume cs:cods,ds:data1
MOV AX, DATA2 : MOV AH,4CH INT 21H main endp cods ends end start cods segment main proc far assume cs:cods,ds:data1 es:data2 start: MOV AX, DATA1 MOV DS, AX
15
段定义加类型和属性说明 Segname SEGMENT [定位类型] alin-type;段起始地址边界值的规定
[组合类型]combine-type 程序连接时段合并方法 [类别] ‘class’,给出连接时段组的类型名。相同的类别装入时位置靠在一起。 ;一般可不用,在有多个模块时,各个程序模块连接时需要的。 Segname ENDS
16
定位类型 Alin-type : PARA 表示段起始于小段,即段地址在 最后0H处。这为 默认设置。 BYTE 段起始于任何地址
WORD 段起始于偶地址 PAGE 段起始于页的边界。最后00H
17
组合类型Combine-type PUBLIC 相同名字分段连接一起,次序由连接命令指定。 COMMON 同名分段有相同起始地址
即相互交盖。连接长度是各个段中最长的。 AT EXP 分段起始地址是exp计算出来的16位值。注意:不能用来指定代码段 PRIVATE 私有段,不与其它同名段合并。 STACK 指明为堆栈段,长度为各段之和 MEMORY 指定该段分配和其他段连在一起
18
程序开始和结束伪操作 在程序的开始可以用NAME或TITLE为模块取名字: 表示源程序结束的伪操作的格式为:
NAME module_name TITLE text 表示源程序结束的伪操作的格式为: END [start] 如没有模块名,就以文件名为模块名。 汇编程序在遇END时结束汇编, 而程序将从START开始执行
19
80386以上CPU的伪指令 一、处理器选择伪操作 。8086 选择8086指令系统 。286 选择80286指令系统
。8086 选择8086指令系统 。286 选择80286指令系统 。286P 选择保护方式下80286指令系统 。386 选择80386指令系统 。386P 选择保护方式下80386指令系统 。486 选择80486指令系统 。486P 选择保护方式下80486指令系统 。586 选择80586指令系统 。586P 选择保护方式下80586指令系统 选择放在整个程序的最前面
20
80386以上CPU的伪指令 二、存储模型 MODEL伪操作 格式:。MODEL MEMORY_MODEL
1) Tiny 数据和代码放在一个段内 2)Small 数据在一个64K数据段内,代码放在另一个64K段内。最常用的模型 3)Medium 代码放在多个段内,一个模块为一个段,数据合在一个64K段内 4)Compact 代码放在一个段内,数据放多个段 5)Large 代码和数据放在多个64K段内。 6)Huge 代码和数据放在多个段内,可超过64K。 7)Falt 允许用户用32位偏移量。但DOS下不允许。
21
80386以上CPU的伪指令 三、简化段定义伪操作 分段更细:常数段与数据段分开;初始化数据段和未初始化分开;近和远数据段分开,便于与高级语言兼容。 .CODE[name] 代码段,段名可选 .DATA 数据段 .DATA? 数据段未初始化 .FARDATA[name] 远数据段,可指段名 .FARDATA?[name] 远数据段未初始化,可指段名 .CONST 常数段 .STACK[size] 堆栈段,可指定大小,默认1KB
22
80386以上CPU的伪指令 简化段定义时,数据段只用.data定义,没有命名 mov ax, @data mov ds, ax
与简化段定义有关的预定义符号 完整段定义中的段名装入寄存器 mov ax,data_seg1 mov ds,ax mov ax,data_seg2 mov es,ax 简化段定义时,数据段只用.data定义,没有命名 mov mov ds, ax
23
简化段定义例 .MODEL SMALL .DATA .FARDATA .CODE ASSUME ES:@FARDATA
START: MOV MOV DS, AX MOV MOV ES, AX : : MOV AX, 4C00H INT 21H END START
24
(二)数据定义及存储器分配伪操作 格式:[变量名] 助记符 操作数1,… ,操作数n [;注释] 助记符 说明数据类型,常用的有以下几种:
助记符 说明数据类型,常用的有以下几种: DB 字节(8位) DW 字(16位) DD 双字(32位) DQ 四字(64位) ,存放双精度浮点数。 DT 十个字节,形成压缩的BCD码。 操作数 把数据放入指定的单元,可是常数、表达式、字符串、地址等。 下例:
25
1)数据定义伪操作:把数据存入存储单元;分配空间; DW和DD可存储偏移地址或完整的地址。 举例:
0 A 0 4 1 0 6 4 0 0 0 1 F B F F 3 C F D 10d 例: 操作数可以是常数,或者 表达式(可以求得一个常数), 如 4 10h 100d 100h DATA_BYTE DB 10,4,10H DATA_WORD DW 100,100H,-5 DATA_DW DD 3*20,0FFFDH -5 60d 汇编程序在汇编期间在存储器中 存入数据,如图所示 0FFFDh
26
注意:1、不能写为 DW ’ABCD‘ 2、用DB与DW来定义字符串的区别 例 :操作数也可以是字符串,如:
例 :操作数也可以是字符串,如: MESSAGE DB ‘HELLO’ 例:DATA DW ‘AB’,’CD’ 注意:1、不能写为 DW ’ABCD‘ 2、用DB与DW来定义字符串的区别 2) 操作数“?”用于保留存储空间,但不存入数据。 如: ABC DB 0,?,?,?,0 DFF DW ?,52,?
27
例:ARY1 DB 100 DUP(?) 3)操作数可以使用复制操作符来复制某个操作数。 格式: ARY3
FF 1 2 3 3)操作数可以使用复制操作符来复制某个操作数。 格式: repeat_count DUP(operand,……operand) repeat_count:表达式,正整数,用来指定括号中的 重复次数。 ARY3 例:ARY1 DB 100 DUP(?) DUP操作可以嵌套, ARY3 DB DUP (0,2 DUP(1,2),0,3)
28
(DW)或整个地址(DD)存入存储器。 用DD操作存入地址时: 第一个字为偏移地址,第二个字为段地址。
例 : PARA_TAB DW PAR1 DW PAR2 DW PAR3 INTER_DATA DD DATA1 DD DATA2 则汇编后的存储情况如图所示
29
PARA_TABLE PAR1的偏移地址 PAR2的偏移地址 PAR3的偏移地址 INTER_DATA DATA1的偏移地址 DATA1的段地址 DATA2的偏移地址 DATA2的段地址 例 的汇编结果
30
则第一条指令应为字节指令,而第二条应为字指令。
例 注意:变量的类型 OPER1 DB ?,? OPER2 DW ?,? … MOV OPER1,0 MOV OPER2,0 则第一条指令应为字节指令,而第二条应为字指令。 OPER1 DB 1,2 OPER2 DW 1234H,5678H … MOV AX,OPER1+1 MOV AL,OPER2 例 程序将指示出错: 两条MOV指令的两个操作数的类型不匹配。
31
作业 4.5
32
5)变量在存储器中偏移地址值如何计算 汇编时,内部有一个地址计数器(位置计数器) 汇编指令时保存指令的偏移地址;
汇编指令时保存指令的偏移地址; 汇编数据段时,计算变量的偏移地址。 ① 段定义开始,位置计数器(LC)置0 ② 根据数据定义语句,按字节数,使位置计数器计数 ③变量偏移地址值就是位置计数器的计数值,也即该变量与段首的距离(字节数) LC中当前值用$表示
33
5)地址计数器与对准: Data segment Data ends JC $+6 例: array1 DW 1,2,$+4,4,$+4
2 ? 4 5 0a ff 例: Data segment array1 DW 1,2,$+4,4,$+4 Array2 DB 5, 0ah, -1, $ Data ends 例: JNE $ JC $+6 ORG伪操作:用来设置地址计数器的值。 ORG EXP 例:ORG 100H DATA1 DW 10 DUP ($), 1000H,$+200H
34
(三)表达式赋值伪操作EQU 程序中常有一些常数,是数据,数据地址或程序地址,多次出现. 直接用数字表示,1,可读性差 2, 修改麻烦 为方便,可用赋值伪操作给它赋予一个名字。 格式如下: Exp_name EQU Expression 表达式:有效的常数表达式,有效的助记符 举例如下: LF EQU ;换行 CR EQU 13 ; 回车 port1 EQU 3F8H ; 端口地址 COM1 W-P EQU WORD PTR B EQU [BP+8] P EQU DS:[BP+8]
35
(1)EQU表达式中:有变量或标号的表达式,则应先定义如: AB EQU DATA__ONE+2 则必须放在DATA_ONE的定义之后。
应用时必须注意的几点: (1)EQU表达式中:有变量或标号的表达式,则应先定义如: AB EQU DATA__ONE+2 则必须放在DATA_ONE的定义之后。 (2)与EQU 相类似, = 伪操作,作为赋值使用。 区别是:EQU 中的表达式名是不允许重复定义的, = 则允许重复定义。 Var1 db 2,5,7,9 Var2 dw 0,10h,-8 Cont EQU $-var1
36
变量、标号的属性 名字项可以是标号或变量名。 标号: 标号在代码段中定义,后面跟冒号:。标号有三种属性:段,偏移及类型。 段属性:
偏移属性: 类型属性: 标号的段起始位置。 标号的偏移地址是16/32位无符号数。 指出该标号是在本段中引用还是在其他段中引用的。 段内称NEAR,对16位段 指针长2字节,32位4字节; 段外称FAR,对16位段 指针长4字节,32位6字节。
37
变量所占用的字节数。 变量: 代码段外的其他段中定义,不跟冒号。 常在操作数出现。有段,偏移及类型三种属性 段属性: 偏移属性: 类型属性:
代码段外的其他段中定义,不跟冒号。 常在操作数出现。有段,偏移及类型三种属性 段属性: 偏移属性: 类型属性: 变量的段起始地址,在一个段寄存器中 16/32位无符号数,从段的起始地址到变量地址之间 的字节数。偏移值等于当前地址计数器的值, 可以用$来表示。 变量所占用的字节数。 属性可用: SEG, OFFSET, TYPE来获取
38
常用操作符 ① 段属性 操作符 SEG 包含在可执行指令中的伪操作呌操作符 一,变量或标号属性操作符:将存储器地址分解。
作用 取段地址 MOV CX, SEG VAR1 ② 偏移属性操作符 offset 格式 offset<变量名>或<标号名> 作用 取其偏移地址 MOV BX, offset Var (LEA BX, Var 等效)
39
常用操作符 3 类型操作符 格式 type<变量名>或<标号名> 作用 取出类型(值)
3 类型操作符 格式 type<变量名>或<标号名> 作用 取出类型(值) 类型:该数据项长度,用以字节为单位表示。 var db 234 var1 dw 1 MOV AX, type Var ;(AX)=1 MOV AX, type Var1; (AX)=2 注:变量表达式的类型属性与变量同 如:mov ax, type var+4 若是标号类型的数值:Far 为 –2, Near 为 -1。
40
常用操作符 ① 格式:length Var 得到分配给Var变量的单元数。对使用DUP定义的变量有不同的值。 其他情况则是1。
② 格式:size Var 得到Var变量所分配的字节总数 例:multi DW 50 DUP (?) length multi 就是50 Type multi 是 2 Size multi 是2*50=100 length和size 操作符只能和数据存储器地址操作数一起使用。
41
二,类型重指定操作符 (一)格式 : 类型 PTR <地址表达式> 类型: byte , word, Dword
功能:对内存操作数类型进行说明或重定义。 PTR的类型优先级高于变量定义伪指令 PTR是有临时性,PTR不分配存储空间 例:INC word PTR [DI] MOV byte PTR [SI] , 0 若无类型说明,汇编程序无法确定为字操作还是字节操作
42
类型重指定操作符 34 12 78 56 90 9a 00 VAR 例2,VAR DW 1234H, 5678H ,90 H
TAB DB 12H,34H,56H,78H,9ah, MOV AL, VAR+2;(类型不匹配) MOV AL, byte PTR VAR+2 (AL)=78H MOV AX, word PTR TAB+2 (AL)=56H TAB 9a
43
类型重指定操作符 12 34 (二)格式:<变量名或标号>LABEL<类型> var2
为当前存储单元定义一个指定新类型 变量类型可以是byte,word,dword,struct, 标号类型可以是near和far 例1:var1 label byte var2 dw 50 DUP (3412H) 这样在100个数组字节中,第一个字节赋予二个不同类型 var1变量为字节类型 var2变量是字类型的 mov ax, var2; ax? mov ah, var1; ah? var2 12 34
44
<变量名或标号>LABEL<类型>
SS <变量名或标号>LABEL<类型> 11 22 33 44 55 66 例2:stack segment dw DUP(?) tos label word stack ends 目的设置堆栈 mov sp, tos 400 aa bb cc dd ee Sp tos
45
三,分离操作符HIGH 和 LOW 接收一个数或地址表达式,HIGH取高字符,low取低字符 例:Var dw 1234H
MOV AL, HIGH Var ; (AL)=?H
46
变量使用的注意 12 34 56 78 90 00 BB CC DD EE ARRY ① 变量类型必须与指令要求相符
① 变量类型必须与指令要求相符 例 WTABLE DW 20 DUP(0) MOV AX , WTABLE MOV AL , WTABLE ② 变量仅对应数据区中第一个数据项, 需对其它数据项进行操作时,必须 用地址表达式写出。 如:mov ax, arry mov cx, arry+4 mov arry+8, cx
47
操作数表达式 操作数项:一个或多个表达式。可以是常数、寄存器、 标号、变量或表达式组成。
汇编程序按优先规则进行计算后可得到一个数值或一个地址。 算术操作符 +、-、*、/ 、 MOD 逻辑操作符 AND、OR、XOR、NOT 关系操作符 EQ(相等)、NE(不等)、LT(小于)、GT(大于) LE(小于或等于)、GE(大于或等于)6种。
48
算术操作符的使用 算术操作符用于地址表达式时,注意: 只有当其结果有明确的物理意义时才是有效的结果。 两个地址相乘是没有意义的 不同段的地址相加是没有意义的 SUM+4,SUM-6表示变量SUM的前移和后移的地址单元
49
高 优 先 级 低 1 圆括号、方括号中的项 2 LENGTH,SIZE、WIDTH、MASK 3 PTR,OFFSET,SEG,TYPE,THIS 4 HIGH、LOW 5 *,/,MOD,SHL,SHR 6 +,- 7 EQ,NE,LT,LE,GT,GE 8 NOT 9 AND 10 OR,XOR
50
作业 4.2 4.3 4.9 4.14 自学 4.4 汇编语言程序的上机过程 要求:读懂程序 掌握上机操作步骤
51
程序的调试 -u 先进入DEBUG并装入我们要调试的程序如: EX_MOVS.EXE
键入: C>debug ex_movs.exe 再键入U后如图所示: -u 18F4: E PUSH DS 18F4: BC SUB AX,AX 18F4: PUSH AX 18F4: B8F MOV AX,18F6 18F4: ED MOV DS,AX 18F4: B8F MOV AX,18F9 18F4: 000C EC MOV ES,AX 18F4: 000E D LEA SI,[0000] 18F4: ES: 18F4: D3E LEA DI,[0000] 18F4: FC CLD 18F4: B MOV CX,0028 18F4: 001B F REPZ 18F4: 001C A MOVSB 18F4: 001D CB RETF 18F4: 001E ADD [BX+SI],AL
52
的当前值,最后一行给出下一条将要执行指令的地址、 机器语言及汇编语言
在确定断点后,就可以用G命令使程序启动运行,同时设定 断点001D如下: -g ld AX=18F9 BX=0000 CX=0000 DX=0000 SP=FFFC BP=0000 SI= DI= DS=18F6 ES=18F9 SS=18F4 CS=18F4 IP=001D NV UP DI PL 2R NA PE NC 18F4:001D CB RETF 程序停在断点处,并显示出所有寄存器以及各标志位 的当前值,最后一行给出下一条将要执行指令的地址、 机器语言及汇编语言
53
我们还可以用D命令分别察看数据段和附加段的有关区域,如 下图所示:
-d18F6:0 18F6: — a……a 16位
Similar presentations