16位汇编语言学习笔记(1)——基础知识

文章目录

  • 1.配置汇编学习环境
    • 1.1 工具下载
    • 1.2 配置环境
  • 2. 汇编命令基础
    • 2.1 简单使用
    • 2.2 常用命令
  • 3. 汇编语言基础
    • 3.1 汇编语言程序与汇编程序
    • 3.2 汇编语言程序的格式和组成元素
    • 3.3 伪指令
      • 3.3.1 符号定义伪指令
      • 3.3.2 变量定义伪指令
      • 3.3.3 段定义伪指令
      • 3.3.4 过程定义伪指令
      • 3.3.5 指令集选择伪指令
    • 3.4 指令系统
      • 3.4.1 数据传送指令
        • 通用数据传送指令
        • 累加器专用传送指令
        • 地址传送指令
        • 标志传送指令
      • 3.4.2 算数运算指令
        • 二进制算数运算指令
          • 加法指令
          • 减法指令
          • 乘法指令
          • 除法指令
        • 十进制数算数运算调整指令
      • 3.4.3 位操作指令
        • 逻辑运算指令
        • 移位指令
          • 算数、 逻辑移位指令
          • 循环移位指令
      • 3.4.5 处理器在控制指令
    • 参考

1.配置汇编学习环境

1.1 工具下载

  1. 首先进入DOSBox官网下载地址
  2. 点击下载
    16位汇编语言学习笔记(1)——基础知识_第1张图片
  3. 安装(双击下载的exe文件,可以选择下载的路径)
    16位汇编语言学习笔记(1)——基础知识_第2张图片
  4. 下载MASM5、LINK、DEBUG
    百度网盘下载地址 提取码: 7azq

1.2 配置环境

  1. 创建一个文件夹am(比如我在D盘下建立),在再创建两个文件夹ASM、MASM
    汇编程序(ASM):用来存放要编译的汇编程序
    编译程序(MASM):用来存放编译程序MASM-5.10、LINK、DEBUG
    16位汇编语言学习笔记(1)——基础知识_第3张图片
  2. 配置dosbox-0.73-3.conf
    在【最近添加】中找到【DOSBox 0.74-3 Options】
    16位汇编语言学习笔记(1)——基础知识_第4张图片
    用记事本打开后,在文末添加如下字段(【D:\am】是我存放am文件夹的路径,在此处需要对应修改)
# 挂载驱动器(将放汇编程序、编译工具文件夹挂载到一个虚拟盘)
mount F: D:\am
# 添加系统临时变量(此时的 F: 代表的是E:\Assembly)
set PATH=%PATH%;F:\MASM;
# 转到 F: 
F: 
# 进入ASM文件夹
cd F:\ASM

16位汇编语言学习笔记(1)——基础知识_第5张图片

1)mount F: D:\am
mount——是挂载命令语句
F:——是虚拟盘,可以是已存在的盘C:/D:/E:,也可以是不存在的盘F:/G:/H:等
D:\am——汇编程序、编译工具文件夹
结果:F: 代表的是D:\am
(2)set PATH=%PATH%;F:\MASM;
将 MASM 文件中的编译程序添加至临时系统变量中,打开软件就添加,关闭就没有了。
相当于 set PATH=%PATH%;D:\am\MASM;,但是DOSBox软件只能读取只是你挂载的虚拟盘,不能这么写。
(3)F:
转到挂载的 F: 盘
(4)cd F:\ASM
进入ASM文件夹。
相当于cd D:\am\MASM,但是DOSBox软件只能读取只是你挂载的虚拟盘,不能这么写。

  1. 扩大屏幕(可选,初始的界面很小,且不能直接拉伸界面)
    在【最近添加】中找到【DOSBox 0.74-3 Options】将
windowresolution=original
output=surface

修改为:

windowresolution=1280x800  # 这个是小写字母 x
output=opengl 

2. 汇编命令基础

2.1 简单使用

  1. 打开DOSBox后,会出现如下界面:
    16位汇编语言学习笔记(1)——基础知识_第6张图片
  2. 进入notepad++ 官网下载地址,并下载并安装
  3. 在notepad++ 中写入如下汇编程序
STACK	SEGMENT  PARA  'STACK'				;定义堆栈段,段名为 STACK(可以取其他的)
		DB 100 DUP('?')						;分配堆栈的大小,设置为100字节,以?填充
STACK	ENDS								;堆栈段结束
DATA	SEGMENT								;定义数据段,段名为 DATA (可以取其他的)
  		STRING	DB 'HELLO!','$'				;定义字符串数据
DATA	ENDS
CODE	SEGMENT								;定义代码段,段名为 CODE (可以取其他的)
		ASSUME CS:CODE, DS:DATA, SS:STACK	;特别重要,将 CS、DS、SS 指向定义的段
START:	MOV  AX,  DATA						;程序开始的地方
		MOV  DS,  AX
		MOV  AX,  STACK
		MOV  SS,  AX
		LEA  DX,  STRING
		MOV  AH, 09H
		INT  21H
		MOV  AH,  4CH
		INT  21H
CODE  	ENDS						
		END START 							;程序结束的地方
  1. 保存"hello.asm"程序
    可以先选择语言【Assembly】,然后保存在【MASM】文件夹下。
    16位汇编语言学习笔记(1)——基础知识_第7张图片
  2. 编译调试, 输入如下命令
    masm hello.asm
    link hello.obj
    debug hello.exe
    16位汇编语言学习笔记(1)——基础知识_第8张图片

2.2 常用命令

  • R命令:查看、改变CPU寄存器的内容
    格式: -r [寄存器]
    功能:显示和修改CPU中寄存器内容和状态标志值
    -r : 显示所有寄存器的内容
    -r ax : 显示某个寄存器的内容
    -r f : 显示和修改状态标志值
    欲修改IF、AF、CF及PF标志,可在显示的各状态标志值之后输入diaccype
    在这里插入图片描述

  • D命令:显示存储单元
    采用的是二进制数的十六进制表示,可读性比较差

    格式:
    -d [地址]
    -d [地址范围]
    

    ① 显示代码段存储单元的内容
    -d cs:0000显示代码段中从0000H开始的128个字节单元的内容
    ② 按指定地址显示存储单元的内容。
    -d ds:0000显示数据段中从0000H开始的128个字节单元的内容
    ③ 按指定地址范围显示存储单元的内容。
    -d ds: 0000 003f

如果第一次使用D命令时,没有指定地址或地址范围,则显示代码段的内容; 其后没有指定地址或地址范围的D命令,将在上一次显示内容的基础上,显示其后128个单元的内容。16位汇编语言学习笔记(1)——基础知识_第9张图片
代码段中偏移地址0000H到000fH的16个存储单元中存放的数据值,对应关系是0000H单元存储的值为F6H,0001H单元存储的值为2DH……,000fH单元存储的值为76H。
……-……v…… 表示上述存储单元中的数据为ASCII码时,在屏幕的显示,如果该数值为控制字符或者不可显示的字符,则以 . 表示。
16位汇编语言学习笔记(1)——基础知识_第10张图片

  • U命令:反汇编命令
    格式:
    -u [地址]
    -u [地址范围]
    
    功能:对指定地址或地址范围的目标代码进行反汇编
    使用反汇编U命令时,将会对目标地址单元的数据反汇编为汇编语言助记符

在EXAMPLE.EXE程序未执行时使用D命令查看数据段内容,得到的数据段DS寄存器的值为13E1H,使用U命令反汇编后查看指令时,系统为程序分配的数据段DS寄存器的值为13F1H,同样都是系统分配的数据段,为什么两者相差了256个单元呢?
原因是磁盘上的EXE文件包括两部分:一部分为装入模块,另一部分为“重定位信息”。DEBUG调试器在载入EXAMPLE.EXE程序到内存时,这两部分均调入内存,在完成对装入模块的重定位后,重定位信息即被丢弃,然后再在同一内存块的用户程序上方(低地址处)偏移地址为00H~FFH的单元自动生成一个有256个字节的数据块,该数据块被称为“程序段前缀”(Program SegmentPrifix,简称PSP)。载入程序时,系统自动给DS,ES,FS和GS赋值,令DS=ES=存放PSP的段基址,FS=GS=0,CS:IP=用户程序的启动地址,然后系统将控制权交给用户程序
用户必须注意系统给DS,ES段寄存器所赋的初值并不等于用户程序数据段、附加数据段的段基址,由于PSP的存在,两者相差了256个字节,因此用户程序一开始就必须对DS进行初始化(程序中如使用ES段,也必须初始化)

  • G命令:执行命令
    格式:-g [=地址1][地址2]
    功能:从地址1开始执行程序,一直执行到地址2。
    若程序能够正确地执行结束,屏幕将显示当前寄存器的执行结果及后一条将要执行的指令。这时用户可以查看寄存器中的数据变化情况,也可以使用D命令查看各个段的信息。用户可以使用两种方法来确定地址1和地址2的具体值:其一,在汇编时,产生LST文件,用文本编辑器查看*.LST文件;其二,在DEBUG中,使用U命令查看程序。例如:在EXAMPLE.ASM程序中,最后一条指令是INT21H,该指令的地址为0018H,故可以使用命令:g=00000018

  • E命令:改变内存中的内容
    格式1:-E地址 [数据表]
    功能:用给定的数据表来替代指定范围的存储单元内容。
    格式2:-E地址
    功能:逐个单元相继修改存储单元内容。
    在这里插入图片描述
    在这里插入图片描述

  • T : 单步执行命令
    格式:-t [指令数]
    功能:执行一条或多条指令。每执行一次,则显示所有寄存器内容和状态标志值。
    如果不指定指令数,则执行当前CS:IP指定地址的一条指令。显示这条指令执行后所有寄存器内容、状态标志值,并显示后一条将要执行的指令。如果指定指令数,则从当前CS:IP指定地址开始执行指定数目的指令,并显示每一条指令执行后的结果。
    T命令执行指令时,如果指令中涉及到数据段,则DEBUG调试器自动显示该数据段中相应单元的数值。
    16位汇编语言学习笔记(1)——基础知识_第11张图片
    在这里插入图片描述
    Flags 中的状态标志的状态表示符号
    16位汇编语言学习笔记(1)——基础知识_第12张图片

  • A命令:以汇编指令的格式在内存中写入一条机器指令
    16位汇编语言学习笔记(1)——基础知识_第13张图片

  • G命令:跳转指令

  • P命令:直接执行完不是单步执行

  • ?命令:查看指令帮助
    格式1: DEBUG/?
    功能:显示DEBUG调试器装载文件的命令格式
    16位汇编语言学习笔记(1)——基础知识_第14张图片

DEBUG [[drive:][path]filename [testfile-parameters]]
DEBUG调试器可选参数中
[drive:]:表示被装载文件所在的驱动器
[path]:表示被装载文件所在的文件夹
filename:表示被装载文件名称
[testfile-parameters]:表示调试参数
注:[]表示可选项
该提示信息指出,具体DEBUG调试器命令可在运行DEBUG调试器后输入?得到显示。

格式2: -?
功能:显示DEBUG调试器命令。该命令可以显示命令的具体内容和参数
16位汇编语言学习笔记(1)——基础知识_第15张图片
16位汇编语言学习笔记(1)——基础知识_第16张图片

  • q 命令: 退出命令
    格式:-q
    功能:退出DEBUG调试程序,返回操作系统。

3. 汇编语言基础

3.1 汇编语言程序与汇编程序

将汇编语言源程序编译成目标程序的加工程序称为汇编程序。这一加工过程称为汇编。
16位汇编语言学习笔记(1)——基础知识_第17张图片

汇编程序与汇编语言程序是两个不同的概念。汇编程序是用来将汇编语言程序编译成机器代码的工具;汇编语言程序是用户根据实际需要编写的程序。

3.2 汇编语言程序的格式和组成元素

汇编语言示例程序:

NAME EXAMPLE

DSEG SEGMENT
DATA1 DB 4 DUP(1), 10H,11,0AH,0,0BH
SUM DB ?
COUNT EQU 9
DSEG ENDS

SSEG SEGMENT 
STACK DB 100H DUP(?)
SSEG ENDS

CSEG SEGMENT
ASSUME CS:CSEG,DS: DSEG,SS:SSEG
START: 
MOV AX, DSEG
MOV DS,AX
XOR AL,AL; AL 清零
MOV CX,COUTN; 设置循环操作的次数
LEA SI,DATA1; SI指向数据区的起始位置
LOOP1: ADD AL,[SI];将SI所指的数据加到AL中
INC SI;SI指向下一个字节
LOOP LOOP1;CX减1计数,减去1后不为0则跳转至LOOP1标号处
MOV SUM,AL;将DATA1 中的9个字节之和送变量SUM
MOV AH,4CH
INT 21H; 返回DOS
CSEG ENDS

ENDS START 

(1)汇编语言程序采用以SEGMENT和ENDS定义的段结构,一个汇编语言程序由若干个段组成。
(2)段中包含两种语句:指令语句,即前面介绍的指令,以及伪指令语句,简称伪指令。
(3)语句中包含若干元素:标识符,保留字,表达式等。

  • 标识符
    标识符是源程序中便于指定和阅读的字符串
    标识符可以由字母A~Z,a~z,数字0~9,专用字符?、.、@、$、_(下画线)等字符组成。除数字外,所有这些字符均可作为标识符的首字符。“.”只能作为标识符的首字符。标识符可由多个字符组成,但仅前31个字符能为汇编程序识别。
  • 保留字
    保留字是汇编程序预留的具有固定用途的字符串。例如,示例程序中的SEGMENT,DB,MOV,CX等所有寄存器名,指令及伪指令助记符,运算符等均属于保留字。在编写源程序时,一般要避免将保留字用于非固定用途。
  • 表达式
    表达式是由常量、变量、标号及运算符等构成的式子。表达式分为数值表达式和地址表达式。
    • 常量:常量分为字面常量、符号常量及串常量。如果一个十六进制常量以字母开头,则须在前面添加数字0以区别于标识符
      字面常量由0~9,A,B,C,D,E,F以及基数后缀,即尾标B,D,H,Q(或O)构成
      符号常量是使用EQU、= 伪指令定义其值的标识符。例如,示例程序中的标识符COUNT被定义为数值9。
      串常量是用单引号括起的一串字符。串常量以单引号中各字符的ASCII码存储
    • 变量
      在汇编语言程序中的变量是存储单元的标识符,即数据存放地址的符号表示。
      (1)变量的段属性:是指变量所在段的段地址。当需要访问该变量时,该段地址一定要在某一段寄存器中。
      (2)变量的偏移属性:变量的偏移属性是指变量所在段的首地址到该变量的偏移量
      (3)变量的类型属性:变量的类型是指存取该变量中的数据所对应的字节数。有字节(BYTE)、字(WORD)、双字(DWORD)、四字(QWORD)及十字节(TBYTE)等类型。变量类型由变量定义时所使用的伪指令决定。例如,示例程序中通过DB伪指令将变量DATA1、SUM定义为字节类型
    • 标号
      汇编语言程序中的标号是机器指令存放位置的标识符,即机器指令存放地址的符号表示。它可作为转移指令或重复控制指令转向目的操作数。例如,示例程序中的LOOP1就是标号,它作为LOOP指令的目的操作数。标号一般只在代码段中定义和引用。由于标号代表了指令的符号地址,所以标号也有3个属性:段属性, 偏移属性,类型属性
    • 数值表达式
      数值表达式是由常量与算术运算符、逻辑运算符或关系运算符构成的式子
      16位汇编语言学习笔记(1)——基础知识_第18张图片
    • 地址表达式
      地址表达式是由常量、变量、标号、寄存器BP、BX、SI、DI内容(在此用方括号括起)和运算符组成的式子
      地址表达式除使用前述运算符外,还可以使用所示如下的运算符:
      16位汇编语言学习笔记(1)——基础知识_第19张图片
  1. 属性定义算符

段超越前缀
该运算符用于给变量、标号或地址表达式临时指定一个段属性,其格式为 段寄存器名:地址表达式段名:地址表达式

MOV AL, ES:[1000H] ; 以(ES)作为段地址,以1000H作为偏移地址
MOV AL, [1000H] ;以(DS)作为段地址,以1000H作为偏移地址送AL (段地址的属性默认为DS,当使用超越前缀时,会改变段的属性)

类型运算符PTR
该运算符用于给变量、标号或地址表达式临时指定一个类型。其格式为: 类型PTR地址表达式

MOV WORD PTR[2000H],0 ; 将偏移地址为2000H的字单元,即2000H和2001H两字节清0。

定义类型运算符THIS
该运算符具有与PTR类似的功能,可用于指定某个变量、标号或地址表达式的类型,但在具体用法上有区别。其格式为标识符EQU THIS类型

  1. 分析运算符

取段地址运算符SEG
该运算符产生其后的变量或标号所在段的段地址。

MOV AX, SEG DATA1;将DATA1所在段的段地址送AX

取偏移地址运算符OFFSET
该运算符产生其后的变量或标号的偏移地址

MOV BX, OFFSET DATA1; 将变量DATA1的偏移地址送BX

取类型运算符TYPE
该运算符产生其后的变量或标号的类型值。
16位汇编语言学习笔记(1)——基础知识_第20张图片
取变量单元数运算LENGTH
该运算符产生其后变量所包含的单元个数。该运算的结果根据该变量定义伪指令中第一个表达式的形式而定。若第一个表达式为重复子句“n DUP(数值表达式)”,则LENGTH运算的结果为重复因子n;否则结果为1。伪指令中“n DUP(数值表达式)”等同于将括号中的表达式重复n次。

取变量总字节数运算符SIZE
该运算符产生其后变量所包含的总字节数。

  • 运算符的优先级
    16位汇编语言学习笔记(1)——基础知识_第21张图片

3.3 伪指令

3.3.1 符号定义伪指令

  • EQU伪指令
    格式:标识符EQU
    表达式功能:用表达式来定义标识符,即使得标识符等同于表达式。
COUNT EQU 9; 定义一个符号常量,使之等同于9
ADDR EQU ES: [BX][SI]; 使得ADDR等同于地址表达式ES: [BX][SI]
  • =伪指令
    格式:标识符 = 表达式功能:与EQU伪指令功能基本相同,但两者中只有 = 伪指令可对同一标识符作重新定义
count =9 
count=count+1

注意:EQU、 = 伪指令仅仅是对程序中某些符号进行等价说明,并不实际分配存储单元,因此,用EQU、 = 伪指令定义的符号不占存储单元

3.3.2 变量定义伪指令

  • DB伪指令
    格式:[变量] DB一个或多个表达式
    功能:告知汇编程序,留出一块内存单元作为字节数据区,并在其中存放各表达式的值,先出现者对应低地址,后出现者对应高地址。若此伪指令中设有DB左边的“变量”,则用此变量来标识新定义的内存单元
    表达式可以是以下四种形式:
    (1)字节常量以及不确定常量“?”。
    (2)重复子句:数值表达式DUP(一个或多个表达式)。
    (3)串常量。
    (4)以上3种形式的任意组合。
DATA1 DB 0,45H,0FFH,?
DATA2 DB 'HELLO!'
DATA3 DB 10,2DUP(2DUP(1,2),3)

《易错点》
其数据在内存中的表示如下图:
先定义的数字存放在低字节,字符串按照字节由低到高依次存放。(“HELLO”中H对应低字节)
16位汇编语言学习笔记(1)——基础知识_第22张图片

  • DW 伪指令
    格式:[变量] DW 一个或多个表达式。
    功能:与DB伪指令功能类似,但定义的是字变量。表达式可以是以下4种形式。
    (1)除了是字数据外,与DB伪指令的(1)、(2)同;
    (2)地址表达式。在此情况下,实际取其偏移地址;
    (3)一个或两个字符组成的串常量;
    (4)以上3种形式的任意组合。

《易错点》

ARRAYW DW  -1,1234H,2 DUP(-32768)
ADDR DW ARRAYW +2
STRING DW 'EH','LL',!O'

其数据在内存中的表示如下图:
数据中低位对低位,高位对高位
字符串中高位对应高位,地位对应地位(“EH”中E对应高地址)
16位汇编语言学习笔记(1)——基础知识_第23张图片

  • DD 伪指令
    格式:[变量] DD 一个或多个表达式。功能:与DB伪指令功能类似,但定义的是双字变量。表达式可以是以下4种形式。(1)除了是双字数据外,与DB伪指令的(1)、(2)同。(2)地址表达式。在此情况下,分别将偏移地址和段地址存放到存储器中,偏移地址对应较低地址。(3)1~4个字符组成的串常量。(4)以上3种形式的任意组合。

除上述3种变量定义伪指令外,还有3字变量定义伪指令(DF伪指令)、4字变量定义伪指令(DQ伪指令)和10字节变量定义伪指令(DT伪指令)。

3.3.3 段定义伪指令

段定义伪指令指示汇编程序如何按段组织程序和使用存储器。

  • SEGMENTENDS伪指令格式:段名SEGMENT [定位方式][组合方式][ ‘类别’]
    功能:SEGMENT和ENDS伪指令用于把程序分成若干逻辑段。这些逻辑段根据其用途的不同分为代码段、数据段、堆栈段和附加段,它们被分别装入由CS、DS、SS和ES所指定的物理段中。
    段名由程序员指定,且起始处和结束处的段名一致。段体为段内的指令和伪指令序列。其后的3个参数一般可任选
  • ASSUME伪指令格式:ASSUME段寄存器:段名 [,段寄存器:段名…]
    功能:该伪指令用于通知汇编程序,CS、DS、SS或ES被设定为哪些段的段地址寄存器,从而在汇编时能知道语句中引用的变量、标号或表达式所对应的段

注意:ASSUME伪指令只是告知汇编程序有关段寄存器将被设定为哪个段的段地址,而段寄存器必须通过指令来设定具体值。
例如:示例程序中在使用上述ASSUME伪指令后,通过如下指令给DS设定具体值。

MOV AX,DSEG
MOV DS,AX
  • ORG 伪指令
    格式:ORG表达式功能:告知汇编程序,使其后的指令或数据从表达式的值所指定的偏移地址开始存放。表达式的值应为0~65535(即0000H~FFFFH)例如:ORG$+10表示其后的指令或数据跳过10个字节存放。其中$表示当前偏移地址。

3.3.4 过程定义伪指令

在程序设计中,常把具有某种功能的程序段设计成一个过程。80x86宏汇编语言用于过程定义的伪指令的格式为

过程名 PROC [NEAR 或 FAR]
; 过程体
过程名 ENDP

其中过程名由程序员指定,且起始处和结束处的过程名一致。过程体为过程内的指令和伪指令序列。定义一个近过程时,参数NEAR可省略

3.3.5 指令集选择伪指令

这类指令一般放在程序的起始位置,用来通知汇编程序以下程序中使用哪一种指令集

16位汇编语言学习笔记(1)——基础知识_第24张图片

3.4 指令系统

3.4.1 数据传送指令

数据传送指令用于寄存器、存储器或输入/输出端口之间传送数据或地址
16位汇编语言学习笔记(1)——基础知识_第25张图片

通用数据传送指令
  • MOV
    格式:MOV目的操作数,源操作数
    作用:MOV目的操作数,源操作数
MOV AX,BX;  AX<-(BX) 将BX的内容送到AX中
MOV CL,80H;CL<- 80H
MOV AL,[2000H]; 将EA为2000H(段地址取DS的值)单元的值送到AL中

说明:

  1. 源操作数不变
  2. 立即数、段寄存器、CS不能作为目的操作数
  3. 源操作数和目的操作数不能同时为存储器操作数
  4. 立即数不能送往段寄存器
  5. 源操作数和目的操作数的类型必须一致,即同为单字节或者同为双字节。当指令中有一个操作数的类型明确时,另一个操作数被视为同一个类型。用"BYTE PTR" 或“WORD PTR” 将一个存储器操作数定义为字节类型或者字类型。当存储器操作数为字类型时,存储器或立即数的高字节对应高地址,低字节对应低地址。
  6. MOV指令的执行不影响标志寄存器

下图反应了MOV指令源地址和目的地址的流动方向
16位汇编语言学习笔记(1)——基础知识_第26张图片

【例1】
MOV [2000H], AX
16位汇编语言学习笔记(1)——基础知识_第27张图片
【例2】MOV WORD PTR [BX+SI], 80H
16位汇编语言学习笔记(1)——基础知识_第28张图片

  • PUSH
    格式: PUSH 源操作数
    作用: 将源操作数压入堆栈。先将SP的内容减2,再将双字节的源操作数传送到SP所指示的堆栈栈顶

【例1】PUSH BX;
16位汇编语言学习笔记(1)——基础知识_第29张图片

  • POP
    格式: POP 目的操作数
    作用: 将栈顶内容送到目的操作数,并将SP的内容加2

【例1】POP AX
高地址对应高字节,低地址对应低字节16位汇编语言学习笔记(1)——基础知识_第30张图片

说明:

  1. 堆栈操作指令中,有一个操作数是隐含的,这个操作数就是SP 指示的栈顶存储单元
  2. 8086、8080 堆栈操作都是字操作,不允许对字节操作
  3. 每执行一条入栈指令,SP自动减2,高字节和低字节先后入栈; 执行出栈指令时,则相反,低字节和高字节先后出栈,SP自动加2。
  4. CS寄存器可以入栈,但是不能随意弹出一个数据到CS.
  5. 遵循先进后出的原则。
  • XCHG
    格式: XCHG 目的操作数, 源操作数
    功能: 把源操作数和目的操作数互换
    说明:
  1. 该指令不允许用立即数和段寄存器作为操作数
  2. 该指令改变源操作数的内容
累加器专用传送指令
  • XLAT
    格式: XLAT
    作用: 把(BX) 和(AL)相加形成的有效地址EA,将该单元中的单字节数传送到AL中。

例:
MOV BX, 4C02H
MOV AL,1DH
XLAT
执行上述命令后, (AL)=55H
16位汇编语言学习笔记(1)——基础知识_第31张图片

说明: 这是一条专门用于AL 和字节表中某一存储单元之间进行数据传送的指令。字节表的首地址在BX中,根据AL设置偏移地址,就可以将该单元的内容送到AL中。

  • IN
    格式: IN 累加器 端口地址
    作用:从指定端口输入一个字节到AL或输入一个字到AX。端口地址以数值的形式给出或者通过DX间接给出。当端口地址大于255时, 只能由DX间接给出。

【例1】
IN AX,16H; 从端口16H输入一个字到AX中
【例2】
MOV DX, 280H
IN AL,DX; 从端口280H输入一个字节到AL

说明: 该指令以及后述的OUT指令时专用于累加器和I/O端口之间进行数据传送的指令。

  • OUT
    格式:OUT端口地址,累加器
    作用: 实现输出,即IN 指令相反的方向的数据传输。
地址传送指令
  • LEA
    格式: LEA目的操作数,源操作数
    作用: 将源操作数的有效地址EA传送给通用寄存器

【例】
MOV BX, 0408H
MOV SI,2000H
LEA BP,[BX+SI+6] ; 将240EH 送BP

  • LDS
    格式:LDS 目的操作数,源操作数
    作用: 将源操作数指定的存储单元中的双字(通常为段地址和有效地址)传送给DS以及目的操作数,高字节送DS,低两字节送目的操作数。

【例1】LDS SI, [40H]
16位汇编语言学习笔记(1)——基础知识_第32张图片

  • LES
    格式: LES 目的操作数,源操作数
    作用: 于LDS的区别仅在于,传送地址时将高两字节送ES, 而不是送DS.
    说明:
  1. 地址传送指令的源操作数必须是存储器操作数,目的操作数必须是16位通用寄存器。
  2. LEA指令与LDS、LES指令所传送的有效地址有区别。LEA指令所传送的有效地址为源操作数的有效地址,而LDS及LES指令所传送的有效地址在源操作数所指的存储单元中。
标志传送指令
  • LAHF
    作用: 将标志寄存器的低八位送至AH
  • SAHF
    作用: 将AH送标志寄存器的低八位送至AH
  • PUSHF
    作用: 与PUSH指令类似,特殊之处仅在于,压入堆栈的是标志寄存器的内容。
  • POPF
    作用:与POP指令功能相似,该指令的特殊之处仅在于,弹出的堆栈的内容是送标志寄存器。

说明:

  1. 数据传送指令中仅SAHF和POPF影响标志寄存器的内容。

3.4.2 算数运算指令

二进制算数运算指令

参与算数运算的二进制数可以是单字节或者双字节数,也可以时无符号或者有符号数
16位汇编语言学习笔记(1)——基础知识_第33张图片
(×表示根据操作结果设置标志;-表示标志不确定;空白表示标志不受影响)

加法指令
  • ADD
    格式: ADD 目的操作数, 源操作数
    作用: 将原操作数加到目的操作数,同时影响状态标志
    ADD执行后对标志的影响:
  1. OF字节运算结果超过字节有符号数的范围(-128 ~ 127)或者字运算超过了字有符号数范围(-32768~32768)时,OF=1; 否则,OF=0; 在把操作数视为有符数时,可通过该标志了解结果是否溢出。
  2. SF 运算结果的最高位是1时, SF=1; 否则SF=0; (即SF 与结果的最高位一致)
  3. ZF运算结果为0时,ZF=1; 否则ZF=0;
  4. AF运算时, D 3 D_3 D3 D 4 D_4 D4产生进位时AF=1, 否则AF=0。
  5. PF运算结果的二进制位1的个数为偶数时,PF=1;

否则PF=0。
6. CF运算时最高位产生进位时,即字节运算结果超出无符号数的范围(0~ 255),字运算的结果超出字无符号数的表达范围(0~65535) 时,CF=1; 否则CF=0。 在把操作数视为无符号数时,可通过该标志了解结果是否溢出。

【例】 ADD AL, BL
设(AL)=0A4H,(BL)=5CH,则指令执行后,(AL)=0,OF=0,SF=0,ZF=1,AF=1,PF=1,CF=1
当把相关数据视为有符号数,从OF=0可知相加结果未溢出,也即AL的内容“0”就是两个有符号数0A4H(-01011100B)和5CH(+01011100B)之和。
当把相关数据视为无符号数,从CF=1可知相加结果产生进位也即“100000000B”就是两个无符号数0A4H(10100100B)和5CH(01011100B)之和。
说明:源操作数和目的操作数类型必须一致,即同为字节或同为字,且两者不能同为存储器操作数(这一点适用于所有双操作数的算术运算指令)。

  • ADC
    格式:ADC 目的操作数, 源操作数
    作用:功能与ADD指令类似,唯一区别是: 将该指令执行前的CF值加入目的操作数中。 该指令主要用于多字节加法运算。

【例】
MOV DX, 2000H
MOV AX, 8A04H
ADD AX,9D00H
ADC DX, 45H
此程序段实现多字节数20008A04H与459D00H的相加。DX存放有被加数的高两字节,AX存放有被加数的低两字节。ADD指令实现两数低两字节的相加,相加后(AX)=2704H,CF=1(相加结果超过两个字节)。ADC指令实现两数高两字节的相加,且将CF(即低两字节相加产生的进位)加至DX,使DX内容为2046H。

  • INC
    格式: INC 目的操作数
    功能与ADD指令基本相同,区别有二: 隐含的源操作数是1 ;不影响CF标志; 该指令常用于某些计数器的计数或者修改地址

【例】
MOV SI, 2000H
MOV AL,[SI]
INC SI
ADD AL,[SI] ; (AL) 为2000H单元和2001单元内容之和。

减法指令
  • SUB
    格式: SBB 目的操作数, 源操作数
    功能: 将目的操作数减去源操作数,同时产生相应的标志(借位)。
  • SBB
    格式: SBB 目的操作数, 源操作数
    作用: 功能与SUB指令基本相同,唯一区别是:目的操作数除减去源操作数外,还要减去该指令执行前的CF值。该指令主要用于多字节的减法运算。
  • DEC
    格式:DEC 目的操作数
    功能:功能与SUB指令基本相同,区别有两点:其一,隐含的源操作数为1;其二,不影响CF标志
  • NEG
    格式:NEG目的操作数
    作用: 对目的操作数取补码,结果送目的操作数
  • CMP
    格式:CMP 目的操作数,源操作数
    作用: 功能与SUB指令基本相同,唯一的区别在于:目的操作数不被差值取代。该指令的作用在于根据两个操作数的大小关系产生状态标志值,以便后续根据状态标志确定流程。
乘法指令
  • MUL
    格式:MUL 源操作数
    作用:实现无符号数的乘法运算。
    16位汇编语言学习笔记(1)——基础知识_第34张图片
    说明:MUL指令影响进位标志CF和溢出标志OF(其他标志不确定) 若乘积的高半部分(字节相乘时的乘积中的AH, 字相乘时乘积的DX) 非零,则CF=OF=1; 否则,CF=OF=0;也即CF=OF=1标志着AH或者DX中放着乘积的有效位。

【例】
MUL CL; AL,CL 中的无符号数之积送AX
MUL [SI] 为错误指令,原因在于计算机无法识别源操作数是字节操作数还是字操作数;
MUL WORD PTR [SI]; AX中的无符号数与SI所指单元的无符号数相乘,乘积送DX和AX。

  • IMUL
    格式:IMUL源操作数
    作用:功能与MUL指令基本相同,区别在于该指令实现有符号数的乘法运算。此指令执行后,CF=OF=1标志着AH或DX中放着乘积的有效位。即标志着AH或者DX 不是对应的低半部分的符号拓展。

例:
MOV AL, OFCH; -4 送 AL
MOV CL, 1FH; +31送CL
IMUL CL; (AL)与(CL)之积-124送AX,即(AL)=84H,(AH)=FFH。此时,CF=OF=0, 标志着(AH) 是(AL)的符号扩展。

除法指令
  • DIV
    格式: DIV源操作数
    作用: 实现无符号数的除法运算
    16位汇编语言学习笔记(1)——基础知识_第35张图片
    说明: 当源操作数是字节类型时,商的范围是0~255(FFH); 当源操作数是字类型时,商的范围是0 ~ 65535(FFFFH)。 超出范围则产生0中断。

MOV AX, 1001H; 4097送AX;
MOV CL,20H; 32 送CL;
DIV CL; (AX)与(CL) 相除,商128送AL, 余数1送AH。即(AL)=80H, (AH)=01H

  • IDIV
    格式:IDIV 源操作数
    作用:功能与DIV指令基本相同,区别在于该指令实现的是有符号除法运算。另外8086/8088指令系统中规定余数的符号与被除数的符号相同。

例如:
MOV CX,4
IDIV CX; 若已知DX,AX中放有4001H, 则该指令执行后,(AX)=1000H,(DX)=0001H
若已知DX,AX中放有-4001H, 则该指令执行后,(AX)=F000H(即-1000H),(DX)=FFFFH(即-1)

  • CBW
    格式:CBW
    将AL中的符号位拓展到AH中(即使AH各位与AL最高位相同),该指令常用在IDIV指令之前。CBW执行后,各状态标志位不确定。

【例1】
MOV AL,76H; +76H 送AL;
CBW ; 0076送AX,即+0076送AX。
【例2】
MOV AL,98H; -68H送AL;
CBW; FF98H送AX, 即-0068H送AX

  • CWD
    格式: CWD
    作用: 与CBW基本相同,区别仅在于是将(AX)的符号位拓展到DX中。
十进制数算数运算调整指令

前面所述的算术运算都是针对二进制数,但人们最为常用的却是十进制数。在用计算机进行算术运算时,可以先将操作数做十→二进制转换,然后做二进制数算术运算,再将结果做二→十进制转换。为了便于十进制数的运算,8086/8088系统还提供了一组十进制数算术运算调整指令,该类指令在4.1 中有详细的介绍。

3.4.3 位操作指令

16位汇编语言学习笔记(1)——基础知识_第36张图片
(×表示根据操作结果设置标志;-表示标志不确定;空白表示标志不受影响。)

逻辑运算指令
  • NOT
    格式: NOT目的操作数
    作用: 将目的操作数按位取反,结果送目的操作数

【例】
MOV AX,0
NOT AX; 使得(AX)为FFFFH

  • AND
    格式:AND 目的操作数,源操作数
    作用:将目的操作数和源操作数按位相与,结果送目的操作数。该指令常用于屏蔽目的操作数的某些位,即使得目的操作数的某些位置置为0,其余保持不变。

  • OR
    格式:OR目的操作数,源操作数
    作用: 将目的操作数与源操作数按位相或,结果送目的操作数。该指令常用于使得目的操作数的某些位置为1,其余位保持不变。

  • XOR
    格式:XOR 目的操作数,源操作数
    作用:将目的操作数与源操作数按位做异或操作,结果送目的操作数。该指令常用于判断两个数中的哪些位不同,或用于改变指定位的状态。

  • TEST
    格式:TEST 目的操作数,源操作数
    作用:与AND指令基本相同,唯一的区别是:目的操作数保持不变。该指令常用于检测某种条件是否满足,但又不希望改变目的操作数的场合。

TEST AL,01H; 可用此指令检测AL最低位的状态。若AL最低位为0,则两个操作数按位相与的结果为0,从而ZF=1; 若AL的最低位为1,则结果为1, 从而ZF=0。

说明:逻辑运算指令中两个操作数不能同为存储器操作数。

移位指令

移位指令包括算数移位指令,逻辑移位指令,循环移位指令。这些指令只有目的操作数而无源操作数,并在指令中给出移位的位数。而且此位数只能用1或者CL表示。

算数、 逻辑移位指令

算数移位指令(SAL,SAR)用于有符号数,而逻辑移位指令(SHR, SHL)用于无符号数。操作数的左移意味着小数点的相对右移。

16位汇编语言学习笔记(1)——基础知识_第37张图片

  • SHR/SAL
    格式: SHL/SAL 目的操作数,计数
    作用: 将目的操作数左移若干位,低位补0,最高位送CF。该指令可以方便的实现有符号数和无符号数乘以 2 n 2^n 2n的运算,不过在使用时,要注意是否会发生溢出。

【例1】
MOV AL,16H
SHL AL,1; 使得(AL)即00010110B左移一位。移位后,(AL)=00101100B,是原值的两倍。
【例2】
MOV BH,OEEH
MOV CL,2
SAL BH,CL; 使BH中的有符号数11101110B(-18)左移两位, 变成10111000B(-72),是原值的4倍。

  • SHR
    格式:SHR 目的操作数,计数
    作用:将目的操作数右移若干位。每右移一位,高位均补0, 最低位送CF。 该指令可以方便的实现无符号数除以 2 n 2^n 2n的运算。

  • SAR
    格式:SHR 目的操作数, 计数
    作用:将目的操作数右移若干位,高位均保持不变 ,最低位送CF.

循环移位指令

16位汇编语言学习笔记(1)——基础知识_第38张图片

  • ROL
    格式:ROL 目的操作数,计数
    作用:将目的操作数循环左移若干位。每左移一位,左移的最高位送给最低位和CF。

  • ROR
    格式:ROR 目的操作数,计数
    作用: 将目的操作数循环右移若干位,每右移一位,右移前的最低位送最高位和CF。

  • RCL
    格式:RCL 目的操作数,计数
    作用: 将目的操作数连通CF循环左移若干位。每左移一位,左移前的最高位送至CF, 左移前的CF送最低位。

  • RCR
    格式:RCR 目的操作数,计数
    作用:将目的操作数连同CF循环右移若干位。每右移一位,右移前的CF送最高位,右移前的最低位送CF。

3.4.5 处理器在控制指令

16位汇编语言学习笔记(1)——基础知识_第39张图片

参考

《汇编语言程序设计》丁辉主编

你可能感兴趣的:(#,汇编与接口技术,汇编)