汇编语言程序格式
汇编语言程序开发
汇编语言程序的语句格式
硬指令&执行性语句
硬指令:使CPU产生动作、并在程序执行时才处理的语句
执行性语句——表达处理器指令,由硬指令构成的语句,它通常对应一条机器指令,出现在程序的代码段中,格式:
1 | 标号: 硬指令助记符 操作数,操作数,... ;注释 |
标号:反映硬指令位置(逻辑地址)的标识符,后跟一个冒号分隔
硬指令助记符:可以是任何一条处理器指令
处理器指令的操作数可以是立即数、寄存器和存储单元
伪指令&说明性语句
伪指令——不产生CPU动作、在程序执行前由汇编程序处理的说明性语句。伪指令与具体的处理器类型无关,但与汇编程序的版本有关
说明性语句——由伪指令构成的语句,它通常指示汇编程序如何汇编源程序:
1 | 名字 伪指令助记符 参数,参数,... ;注释 |
名字:反映伪指令位置(逻辑地址)和属性的标识符,后跟空格或制表符分隔,没有冒号
伪指令助记符:定义字节数据和字符串的DB就是伪指令
伪指令的参数可以是常数、变量名、表达式等,可以有多个,参数之间用逗号分隔
标识符
标号和名字是符合汇编程序语法的用户自定义的标识符
标识符一般最多由31个字母、数字及规定的特殊符号(如 _、$、?、@)组成,不能以数字开头。默认情况下,汇编程序不区别标识符中的字母大小写。一个程序中,每个标识符的定义是唯一的,还不能是汇编语言采用的保留字。
保留字是汇编程序已经利用的标识符,主要有:
- 硬指令助记符——例如:
MOV、ADD
- 伪指令助记符——例如:
DB、EQU
- 操作符——例如:
OFFSET、PTR
- 寄存器名——例如:
AX、CS
汇编语言源程序框架
简化段定义的源程序框架
1 | .model small ;存储模型伪指令.model,small表示小型模式 |
MASM
5.0/5.1不支持.startup
和.exit
,可修改如下
1 | .model small ;存储模型伪指令.model,small表示小型模式 |
完整段定义的源程序框架
1 | stack segment stack |
汇编语言程序的开发过程
DOS系统功能调用
DOS系统主要分配21H号中断,用于程序员调用DOS操作系统工功能
- 中断调用指令:
INT 21H
在AH寄存器中设置系统功能调用号
字符输入(01H)
从键盘读入一个字符,并使用AL保存出口参数
1 | MOV AH,01H |
字符输出(02H)
在显示器当前光标位置显示给定字符,且光标右移一个字符位置,使用DL作为入口参数
1 | MOV AH,02H |
字符串输入(0AH)
需要事先在主存设置用于保存输入字符串的缓冲区,使用DS:DX
作为出口参数
- 缓冲区的第1字节填入最多欲接收的字符个数(包括回车符)
- 缓冲区的第2个字节存放实际输入的字符个数(不包括回车符)
- 从第3个字节开始存放输入的字符串,实际输入字符数多余定义数时,多出的字符被丢弃
1 | buffer db 81 ;可能输入的最大字符数 |
字符串输出(09H)
需要事先将欲显示的字符串保存在主存中
- 设置入口参数
DS:DX
等于该字符串在主存中的首地址 - 字符串必须以
$(24H)
结束
1 | string db 'hello,everybody','$' |
按键判断(0BH)
仅判断当前是否有按下的键,设置输出参数AL后退出。
AL = 0
没有按键AL = FFH
已经按键
参数&变量&标号
数值型参数
常数
十进制常数 -- 以D/d结尾,默认情况后缀可省略
十六进制常数 -- 以H/h结尾
八进制 -- 以Q/q结尾
二进制 -- 以B/b结尾
字符串常数 -- 用英文缩略号括起来的单个字符或多个字符
符号常数 -- 利用一个标识符表达一个数值。符号定义伪指令有EQU和=
1 | 符号名 equ 数值表达式 |
EQU用于数值等价时不能重复定义符号名,但是"="允许重复赋值
1 | eg: |
数值表达式
算术运算符:+,-,*,/,mod
逻辑运算符:and,or,xor(异或),not
移位运算符:shl,shr
关系运算符:eq,ne,gt(大于),lt(小于),ge(大于等于),le(小于等于)
- 用FFFFH(补码-1)表示真
- 用0000H表示假
1 | eg: |
高低分离符:high(高字节), low(低字节), highword(高字),lowword(低字)
1 | mov ah, high 8765h |
变量定义伪指令
格式
1 | 变量名 伪指令 初值表 |
变量名:用户自定义的标识符,表示初值表首元素的逻辑地址。变量名可以没有,在此情况下直接为初值表分配空间,无符号地址
初值表:用","分隔的参数,主要由数值常数、表达式、"?","DUP"组成
- "?"表示初值不确定
- 重复初值可以用DUP进行定义
1 | 重复次数 dup(重复参数) |
- 变量定义伪指令有
DB、DW、DD、DF、DQ、DT
定义字节单元伪指令DB
用于分配一字节或多字节单元,初值表中的每个数据一定是字节量(Byte),可以是\(0\sim 255\)的无符号数,或\(-128\sim +127\)带符号数
1 | .data |
存储单元 | 偏移地址 |
---|---|
43h(C) | 0007H |
42h(B) | 0006H |
41h(A) | 0005H |
——(?) | 0004H |
64h(100) | 0003H |
64h(100) | 0002H |
fbh(-5) | 0001H |
61h(a) | 0000H |
定义字单元伪指令DW
用于分配一个或多个字单元,初值表中的每个数据一定是字量(Word),一个字单元可用于存放任何16位数据,如:一个段地址、一个偏移地址、两个字符、\(0\sim 65535\)之间的无符号数、\(-32768\sim +32767\)之间的带符号数
1 | wnum equ 5678h ;定义wnum为常量 |
变量实质表达的是主存地址
仅使用变量名或者加个常量是直接寻址
再加一个寄存器是寄存器相对寻址
加两个寄存器是基址变址相对寻址
定义双字单元伪指令DD
用于分配一个或多个双字单元,初值表中的每个数据一定是一个32位的双字量
可以用来表达16位段地址和16位偏移地址的远指针
其他数据定义伪指令DF&DQ&DT
定义3字伪指令DF:为一个或多个6字节变量分配空间及初始化
定义4字伪指令DQ:为一个或多个8字节变量分配空间及初始化
定义10字节伪指令DT:为一个或多个10字节变量分配空间及初始化
练习:定义一个缓冲区,包含33H、34H、35H、36H四个字节字符,把这四个数据复制20遍,存入接着的缓冲区,最后显示出复制结果
1 | source db 33j, 34h, 35h, 36h |
定位伪指针ORG&EVEN&ALIGN
1 |
|
1 |
|
type 名字/标号
返回一个字量数值,表明名字或标号的类型;对字节、字、双字变量依次返回1,2,4