汇编语言伪指令
指示性语句中的位操作命令, 称为伪指令
1. 数据定义伪指令
(1). 格式
[变量名] 位操作 操作数1, 操作数2 ...
定义数据伪操作有以下五种
伪操作 | 作用 | 变量占据内存 |
---|---|---|
DB | 定义变量为字节类型 | 8位 |
DW | 定义变量为字类型 | 16位 |
DD | 定义变量为双字类型 | 32位 |
DQ | 定义变量为四字类型 | 64位 |
DT | 定义变量为十字节类型 | 80位 |
(2). 操作数
数据定义伪操作后的操作数可以是常数、表达式或字符串
举例
DATA DB 21H, 34H ;定义包含两个元素的字节变量DATA
DATA2 DW ? ;为变量DATA2分配2字节的空间,初值为任意值
(3). 重复操作符 DUP
[变量名] 数据定义伪操作 n DUP (初值, ...)
圆括号中为重复的内容, n为重复次数
2. 符号定义伪指令
名字 EQU 表达式
举例
;定义
CR EQU 0DH ;表示 CR = 0DH
TEN EQU 0AH ;表示 TEN = 0AH
;程序段使用
MOV AL, TEN ;AL <- 0AH
如果要对EQU定义过的符号重复定义, 使用 “=” 伪指令
3. 段定义伪指令
段名 SEGMENT [定位类型] [组合类型] ['类别']
...
段名 ENDS
(1). 定位类型
告诉汇编程序如何确定逻辑段的地址边界
定位类型 | 说明 |
---|---|
PARA(默认定位类型) | 逻辑段从1个节(16字节定义为1个节)的边界开始, 段起始物理地址为 XXXX0H |
BYTE | 逻辑段从字节边界开始, 即可以从任何地址开始, 本段的起始地址紧接在前一个段的后面 |
WORD | 逻辑段从字边界开始, 即本段的起始地址必须是偶数 |
PAGE | 逻辑段从页(256字节定义为1页)边界开始, 段起始物理地址为 XXX00H |
(2). 组合类型
组合类型主要用在多模块程序中。组合类型用于告诉汇编程序, 当一个逻辑段装入存储器时, 它与其他段如何进行组合。
组合类型 | 说明 |
---|---|
NONE(默认定位类型) | 本段与其他逻辑段不组合, 即对不同程序模块中的逻辑段, 即使具有相同的段名, 也分别作为不同的逻辑段装入内存而不组合 |
PUBLIC | 具有相同段名的逻辑段在汇编时, 组合在一起 |
STACK | 堆栈段具有相同的段名时, 组合在一起 |
COMMON | 对于不同程序模块中用COMMON说明的同名逻辑段, 连接时装入同一个地址, 即每个逻辑段重叠在一起, 长度等于原来最长的, 重叠部分的内容是最后一个逻辑段的内容 |
MEMORY | 当几个逻辑段连接时, 本逻辑段定位在地址最高地方, 多个MEMORY段, 将第一个遇到的作为MEMORY段, 其余的为COMMON段 |
AT 表达式 | 将表达式的值多为定位段地址 |
(3). 类别
用单引号括起来的字符串,如’CODE’、’STACK’等,其作用是:当几个程序模块进行连接时,将具有相同别名的逻辑段装入连续的内存区域,类名相同的逻辑段按先后顺序排列,没有类名的逻辑段与其他无类别的逻辑段一起连续装入内存。
4. 设定段寄存器伪指令
ASSUME 段寄存器名:段名,[段寄存器名,段名 ...]
ASSUME伪指令用于向汇编程序说明定义的逻辑段属于何种类型的逻辑段
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE, ES:EDATA, DS:DATA, SS:STACK
MOV AX, DATA
MOV DS, AX ;将数据段的段地址复制到DS寄存器
MOV AX, EDATA
MOV ES, AX ;将附加段的段地址复制到ES寄存器
MOV AX, STACK
MOV SS, AX ;将堆栈段的段地址复制到SS寄存器
...
CODE ENDS
5. 过程定义伪指令
将具有某种功能的程序段看作一个过程(即子程序),它可以被别的程序调用(CALL)
过程名 PROC NEAR/FAR
...
RET
过程名 ENDP
6. 宏定义伪指令
宏名 MACRO [形式参数, ...]
宏体
ENDM
举例:两个数适合的宏定义和宏调用
DADD MACRO X, Y, Z
MOV AX, X
ADD AX, Y
MOV Z, AX
ENDM
...
DADD DATA1, DATA2, SUM
7. 举例
- 从键盘输入一个字符串,并输出该字符串
DATA SEGMENT WORD PUBLIC 'DATA'
ORG 00H
CONTENTS DB 50, 0, 50 DUP (00h) ;字符串缓冲区
DATA ENDS
EXTRA SEGMENT WORD PUBLIC 'EXTRA'
EXTRA ENDS
CODE SEGMENT WORD PUBLIC 'CODE'
INITIIALIZE PROC ;用来初始化段寄存器的过程
MOV AX, EXTRA
MOV ES, AX
MOV AX, DATA
MOV DS, AX
RET
INITIIALIZE ENDP
TERMINATE PROC ;用来退出程序的过程
MOV AH, 4CH
INT 21H ;因为程序直接退出, 可以不需要加RET
RET
TERMINATE ENDP
PRINTLN PROC ;换行的过程
PUSH AX
PUSH DX ;过程中要用到这两个寄存器, 先把原来的值存到栈里
MOV AH, 2 ;功能号2是字符显示
MOV DL, 0DH ;DL寄存器存放打印字符, 这里是0D是换行的意思
INT 21H ;中断操作, 进行打印字符
MOV DL, 0AH ;0A是光标指向第一个字符的意思
INT 21H ;中断操作
POP DX
POP AX ;将原来的值再放回对应的寄存器
RET ;过程结束, 返回
PRINTLN ENDP
INPUT_STRING MACRO STRING_BUFFER_ADDRESS ;字符串输入过程
PUSH DX
PUSH AX
MOV DX, OFFSET STRING_BUFFER_ADDRESS ;字符串缓冲区的偏移地址放到DX寄存器
MOV AH, 0AH ;功能号是0AH表示字符串输入
INT 21H ;中断操作, 输入字符串
CALL PRINTLN ;输入结束, 调用换行过程
POP AX
POP DX
ENDM
OUTPUT_STRING MACRO STRING_BUFFER ;字符串输出过程
PUSH CX
PUSH BX
PUSH DX
PUSH AX
XOR CX, CX ;清空CX值
MOV BX, OFFSET STRING_BUFFER ;获取字符串缓冲区首地址
MOV CL, BYTE PTR [BX+1] ;获取字符串长度, 存入CL
ADD BX, 2 ;BX = BX + 2
ADD BL, CL ;BL = BL + 2
MOV BYTE PTR[BX], 0DH ;将换行符存入偏移地址为BX内容的内存
INC BX ;BX = BX + 1
MOV BYTE PTR[BX], 0AH ;将0AH符存入偏移地址为BX内容的内存
INC BX
MOV BYTE PTR[BX], '$' ;结尾放入$
MOV DX, OFFSET STRING_BUFFER ;将字符串缓冲区地址放入DX
ADD DX, 2 ;DX指向输入内容的第一个位置
MOV AH, 09H ;DOS软中断, 09H表示字符串显示
INT 21H ;中断
POP AX
POP DX
POP BX
POP CX
ENDM
ASSUME CS:CODE, ES:EXTRA, DS:DATA
START:
CALL INITIIALIZE ;调用初始化过程
STRING_BUFFER_ADDRESS = STRING_BUFFER ;获取内容地址
INPUT_STRING STRING_BUFFER_ADDRESS ;输入字符串
OUTPUT_STRING STRING_BUFFER ;显示字符串
CALL TERMINATE
CODE ENDS
END START
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/122846.html