[TOC]
上一篇笔记:https://www.cnblogs.com/Tony100K/p/11653755.html
转移类指令
-
JMP Label 段内直接转移
-
MOV BX,1200H JMP BX执行完之后 IP=1200H了
-
MOV BX,1200
-
JMP WORD PTR[BX]段内间接转移,1200和1201这两个单元送给了IP
-
段间转移也是32位 JMP FAR Label
-
间接转移 JMP DWORD PTR[BX] DWORD指32位
-
低地址送IP,高地址送CS
-
条件转移范围只有 -128到127
-
统计内存数据段中以TABLE为首地址的100个8位带符号数中的正数\负数和零的个数
-
START: XOR AL,AL MOV PLUS,AL MOV MINUS,AL MOV ZERO,AL LEA SI,TABLE MOV CX,100 CHECK: LODSB OR AL,AL JS X1 JS X2 INC PLUS JMP NEXT X1: INC MINUS JMP NEXT X2: INC ZERO NEXT: DEC CX JNZ CHECK HLT
循环控制指令
-
范围也非常小 是-128-127的
-
循环次数CX
-
无条件循环LOOP 只要CX不等于0
-
LOOPZ CX不等于0,ZF等于1继续循环
-
LOOPNZ CX不等于0,ZF等于0继续
-
在以DATA为首地址的内存数据段中,存放有200个16位有符号数,找出其中最大和最小的符号数,并分别放在MAX和MIN为首的内存单元中
-
START: LEA SI,DATA MOV CX,200 CLD LODSW MOV MAX,AX MOV MIN,AX DEC CX NEXT: LODSW CMP AX,MAX JG LARGE CMP AX,MIN JL SMALL JMP GOON LARGE: MOV MAX,AX JMP GOON SMALL: MOV MIN,AX GOON: LOOP NEXT HLT
过程调用指令
- 段内调用
- CALL TIMER
- CALL WORD PTR[SI]
- SI后的两位送给IP
- 段间调用
- CALL FAR TIMER
- CALL DWORD PTR[SI]
- RET 返回指令,子程序的最后一条指令必须是RET
中断控制指令
- 是一个远过程调用,需要记录FLAGS
- INT n之后n*4就是存放中断服务子程序入口地址的单元偏移地址
- *
执行过程
- FLAGS压栈
- INT 指令的下一条指令的CS\IP压栈
- n*4得到存放中断向量的地址
- 将中断向量送给CS IP
- 转入中断服务程序
处理器控制指令
标志位操作
-
CLC 清零标志位
-
STC 置1标志位
-
CMC 取反C
-
CLD
-
STD
-
CLI 关中断
-
STI IF置1 开中断
汇编语言源程序
过程
- 输入汇编语言源程序 .ASM
- 汇编 .OBJ
- 链接 .EXE
- 调试 最终环境
语句类型
- 指令性语句 CPU执行的语句
- 指示性语句 不执行 告诉汇编程序定义了多大内存等作用
格式
-
[标号:][前缀]助记符[操作数],[操作数][;注释]
-
伪指令助记符 操作数[,操作数,...][;注释]
常量
- 数字常量
- 字符串常量 'ABCD' 汇编时被译成对应的ASC码
变量 内存单元的符号地址
- 段值 变量所在的段地址
- 偏移量 变量所指单元的偏移地址
- 类型
表达式
-
算术 逻辑 关系运算
-
取值运算符
-
OFFSET 获得变量或者标号的偏移地址
-
SEG 获得变量或者标号的段地址
-
MOV AX,SEG 去变量的段地址送给DS MOV DS,AX MOV BX,OFFSET DATA 取变量的偏移地址送给BX
-
属性运算符
-
MOV BYTR PTR[BX],12H 字节12H MOV WORD PTR[BX],12H 字0012H
-
伪指令
作用
- 定义变量
- 分配存储器
- 定义逻辑段
- 指示程序开始和结束
- 定义过程
数据定义伪指令
指令助记符 | 大小 |
---|---|
DB | 1字节 |
DW | 1字 |
DD | 2字 |
DQ | 4字 |
DT | 10字 |
$$ \begin{array}{l}{\text { DATAI DB } 11 \mathrm{H} \text { , 22 H, 33H, 44H }} \ {\text { DATA2 DW } 11 \mathrm{H}, 22 \mathrm{H}, 3344 \mathrm{H}} \ {\text { DATA3 DD } 11 \mathrm{H}^{*} 2,22 \mathrm{H}, 33445566 \mathrm{H}}\end{array} $$
第二行的11H就相当于0011H 第三行的22H就是00000011H
注意高位对应高地址
DATA1 DB 'ABCD',66H 注意'ABCD'是四个变量
重复操作符
为一个区域各单元设置相同的初值 M1 DB 10 DUP(0) 定以一个以M1为首地址的10个字节单元,并且每个字节单元的初值都是0
MEM1 DB 34H,'A',?(问号表示一个随机数,占1个字节单元) DW 20 DUP(?) 40个单元的随机值
$$ \begin{array}{l}{\text { M1 DB 'How are you?" }} \ {\begin{array}{ll}{\text { M2 DW 3 DUP(11H), 3344H }} \ {\text { DB } 4 \text { DUP ( 2 ) }} \ {\text { ( M3 DB 3 DUP (22H, 11H, ?) }}\end{array}}\end{array} $$
符号定义伪指令
- EQU 用一个符号代替表达式
- 符号名 EQU 表达式
- EQU不会占用内存空间
段定义伪指令
-
说明逻辑段的起始和结束
-
说明不同程序模块中同类逻辑段之间的练习形态
-
SEGMENT [定位类型][组合类型][类别]
ENDS
-
DATA SEGMENT MEM1 DB 11H,22H MEM2 DB 'HELLO' MEM3 DW 2 DUP (?) DATA ENDS
-
段名也表示逻辑段的段地址
-
变量在逻辑段中的位置就代表了它的偏移地址
设定段寄存器伪指令
- ASSUME 段寄存器名:段名
结束伪指令
- END [标号]
- 只有代码段不需要初始化
过程定义伪指令
过程名 PROC [NEAR/FAR] (段内/段外)
RET 负责返回断点
过程名 ENDP
-
过程名是过程体的入口地址
-
DELAY PROC PUSH BX PUSH CX MOV BL,2 NEXT:MOV CX,4167 W10M:LOOP W10M DEC BL JNZ NEXT//一共循环了2*4167次 POP CX POP BX RET DELLAY ENDP
-
CALL DELAY 调用延时子程序
宏定义伪指令
-
与过程不同,不能成为一段可以独立执行的代码,只能和源程序一起用
-
宏命令名 MACRO <形式参数>
ENDM
-
DADD MACRO X,Y,Z MOV AX,X MOV AX,Y MOV Z,AX ENDM
-
DADD DATA1,DATA2,SUM 来进行调用
-
形参和实参的位置必须一一对应
调整偏移量伪指令
ORG 表达式(要求计算结果为非负常数)
DATA SEGMENT
ORG 1200H
BUFF DB 1,2
DATA ENDS
这样,BUFF的偏移地址就变成了1200H
系统功能调用
- BIOS 驻留在ROM的基本输入输出系统
DOS(磁盘操作系统)功能调用的基本步骤
- 将调用参数装入指定的寄存器
- 将功能号装入AH
- 按中断类型号调用DOS中断
- 检查返回参数是否正确
MOV AH,功能号 <置相应参数>
INT 21H
单字符输入
MOV AH,01
INT 21H
可以敲一下键,键在AL中
GET KEY:MOV AH,1
INT 21H
CMP AL,'Y'
JZ YES
CMP AL,'N'
JZ NO
JMP GET KEY
字符串输入
-
AH<-- 功能号10
-
DS:DX<---字符串在内存中的存放地址
-
DAT1 DB,20,?,20,DUP(?)//在数据段中定义 LEA DX,DAT1 MOV AH,0AH INT 21H
单字符输出
-
MOV AH,2 MOV DL,41H INT 21H
字符串输出
- AH=09H
- 被显示的字符串必须以'$'为结束
返回操作系统功能
- 功能号 4CH
- 常用于程序结尾处
来源:oschina
链接:https://my.oschina.net/u/4380991/blog/3359482