第四章:汇编语言及其程序设计

本文介绍了汇编语言的程序运行步骤,包括编辑、汇编、链接生成可执行文件的过程。重点讨论了汇编语言语句格式,操作数类型如立即数、寄存器数和存储器数,以及各种寻址方式,如立即寻址、寄存器寻址和存储器寻址。此外,还详细阐述了数据传送、算术运算等指令,并提到了控制转移指令,如跳转和循环。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、汇编语言概述

①运行汇编语言程序的步骤

编辑程序-> 汇编语言源程序(用汇编语言写的程序)

->汇编程序(将源程序翻译成二进制代码)->浮动目标文件.boj文件

->连接程序->可执行文件.exe文件

②汇编语言语句格式

[名字]        操作符        操作数 [;注释]

1.一条汇编语言语句唯一不可缺少的是操作符,其余皆可没有

如:XLAT(它的操作数隐含了,是固定的)

2.操作符与操作数之间以空格隔开,不同操作数之间以逗号隔开

3.名字:

(1)标号:指令符号地址        标号与操作符以冒号隔开

(2)变量名:数据符号地址        变量名与操作符之间以空格隔开

4.操作数

(1)立即数,指令中直接含有指令需要的操作数,是指令的一部分

(2)寄存器数,操作数在寄存器中

(3)存储器数,操作数在存储器中

例如:

L:MOV AX,[2000H];将存储单元位置为DX:2000H的一个字取出放入AX

DATA1  DB  12H,?,2+6

XLAT;换码

二、汇编语言指令中操作数的寻址方式(指令的寻址方式)

[名字]        操作符        操作数 [;注释]

①段寄存器和存储器操作数不能同时作为目的操作数和源操作数

②CS不能作为目的操作数

一、寻址方式的不同种类

①立即寻址

②寄存器寻址

③存储器寻址:

(1)直接寻址

(2)寄存器间接寻址

(3)寄存器相对寻址

(4)基址变址寻址        (基址寄存器:BX,BP  变址寄存器: DI,SI)

(5)相对基址变址寻址

二、三种不同的寻址方式

①立即数寻址:操作数是指令的一部分。

1°汇编语言语句规定

(1)立即数如果表示成 以字母开头的十六进制数,则应当以数字0做前缀

如 :MOV  BX,0AB12H ;立即数AB12H在汇编语句中应以数字0做前缀,标明其为一个数字

(2)数制用后缀表示,缺省时表示十进制数

如:MOV  AL,12;立即数12D,十进制的12

        MOV  AH,12H;十六进制的12H,0012H

        MOV  AL,10;立即数10D,十进制的10

        MOV  AL,10B;立即数10B 实际上是00000010B 与AL大小相同

底层的二进制代码不同进制的立即数都会汇编成同样的二进制数

立即数的位数与目的操作数的位数相同,即立即数的位数不需要指定,且立即数不能作为目的操作数

如:

MOV AL,12H;这里的立即数是8位的,12H

MOV AX,12H;这里的立即数是16位的,0012H

②寄存器寻址:操作数在CPU的某个寄存器中,指令指定寄存器号

不同的寄存器号

(1)8位:AH,AL,BH,BL,CH,CL,DH,DL

(2)16位:AX,BX,CX,DX,SI,DI,BP,SP//不可拆分的十六位

(3)段寄存器:

        1.CS不能当作目的操作数

        2.两个段寄存器不能同时作为目的操作数和源操作数

        3.立即数不能直接送给段寄存器

如:MOV  DS,AX;段寄存器DS作为目的操作数

③存储器寻址:操作数在存储器中,汇编语言语句需要给出有效地址(段内偏移),以及在不确定存储器操作数大小的情况下需要用PTR语句指出

注意:两个存储器操作数不能同时作为目的操作数和源操作数

在汇编语言中,用 [有效地址] 表示存储器寻址

1°8086下(有效地址为16位)

EA(有效地址)=\begin{bmatrix} BX&\\BP& \end{bmatrix}+\begin{bmatrix} SI&\\DI& \end{bmatrix}+\begin{bmatrix} 8-offset&\\16-offset& \end{bmatrix}

其中:

BX(基址寄存器)

BP(栈基址寄存器)

————————————

SI(源变址寄存器)

DI(目的变址寄存器)

————————————

偏移量可以是寄存器AL,AX 如[BX+AL]

默认段约定

BP(栈基址寄存器)、SP(栈顶指针寄存器):SS  (SP隐含于PUSH和POP操作)

IP(指令指针):CS//        用于取指

其他情况:DS

段超越

若不想使用默认段,可以指明所用段

MOV  AL, DS:[BP];BP的默认段是SS,利用DS:[]说明段超越

寻址方式

(1)直接寻址:直接用立即数当做段内偏移

MOV  BX,[10H];用0010H当作十六位有效地址,默认段DS

(2)寄存器间接寻址:直接用寄存器号当作偏移地址 //基址、变址寄存器均可

MOV BX,[BX]

MOV BX,[DI];默认段DS

(3)寄存器相对寻址:用寄存器操作数+立即数作为偏移地址

MOV BX,[BX+10H]

MOV BX,[DI+10H]

(4)基址变址寻址:用基址寄存器 + 变址寄存器 作偏移地址

MOV BX,[BX+SI]

MOV BX,[BP+DI];默认段为SS

(5)相对基址变址寻址:用基址寄存器 + 变址寄存器+立即数 作偏移地址

MOV BX,[BX+SI+27];27D

三、转移地址的寻址方式(跳转指令的不同跳转方式)

①段内相对寻址:IP+=偏移量,IP直接由标号位置赋值  (仅此可实现条件跳转)

②段内间接寻址:IP+=存储器操作数/寄存器操作数

③段间直接寻址:CS:IP直接由标号位置赋值

④段间间接寻址:CS:IP,存储器双字 操作数低16位送IP,高16位送CS

①段内相对寻址:<标号>

汇编语言语句用标号表示,而机器指令用的是位移量,即标号的有效地址与当前IP之差

短跳转:SHORT//8位

近跳转(近类型):NEAR PTR//16位

JMP NEAR PTR A1

JMP SHORT A1

虽然表示的是跳转到A1去,但是实际上机器指令中有一个对应的偏移量

②段内间接寻址:<16位寄存器操作数 或 16位存储器操作数 替换IP的值>

JMP BX

JMP WORD PTR [BX+2];DS:BX+2D

③段间直接寻址:<标号>

远跳转(远类型):FAR PTR

JMP FAR PTR A1

标号的符号地址 包含一个段地址和段内偏移 直接给CS和IP

④段间间接寻址:<32位存储器操作数 分别替换CS 和 IP,IP都用低地址数>

JMP DWORD PTR [SI];寄存器间接寻址

四、指令系统(指令的集合)

 注意:

        1.CS不能当作目的操作数

        2.两个段寄存器不能同时作为目的操作数和源操作数

        3.立即数不能直接送给段寄存器

        4.存储器操作数不能同时作为目的操作数和源操作数

        5.XCHG不允许使用段寄存器

        6.

隐含默认操作数的指令:

PUSH、POP:SS:SP

PUSHF、POPF:标志寄存器,SS:SP

LDS(指针送寄存器和段寄存器指令):DS

XLAT(换码):AL 和 BX        XLAT ; 相当于MOV AL,[BX+AL]

IN/OUT :AL、(DX)        IN AL,n

ADC(带进位加法):CF

SBB(带接位减法):CF

MUL(无符号数乘法):AL(字节乘)、AX(字乘)        MUL SRC;AX<-AL*SRC

DAA(BCD码):AL、

JMP:IP / CS

一、数据传送指令

MOV

MOV DS,AX        //MOV中数据段可以作为目的操作数,可以用立即数传给寄存器,寄存器传给段寄存器实现 立即数传给段寄存器

MOV WORD PTR [BX],AX

PUSH

PUSH AX

PUSH WROD PTR [BX]

POP

POP AX

POP DWORD PTR[DI]

PUSHF/POPF

弹栈和压栈的操作数均变成了标志寄存器低16位(Pentium下的低16位,8086就是标志寄存器)

XCHG(交换) eXCHanGe

XCHG WORD PTR [BX],AX     //不能同时存储器操作数喔

XCHG AX,BX

————————————————————————————————————————

LEA(存储器寻址的有效地址EA送寄存器) Load Effective Address

LEA CX,[BX+102H]           //这里目的操作数不能是段寄存器

//CX的值等于

ADD BX,102H

MOV CX,BX+102H

//当然LEA没有改变 BX的值,这里改变了

LDS(指针(存储器操作数) 送 寄存器和段寄存器指令 )  隐含段为DS

LDS DI,[BX]

DS:[BX]16位 赋值给 DI   //具体赋值多少位给目的操作数 要看目的操作数的位数

DS:[BX+2]存储器单元16位 赋值给DS

—————————————————————————(源操作数只能是存储器操作数)

XLAT(换码) transLATe   //可以实现非压缩BCD码 到 ASCII码的转换    AL、BX

XLAT (操作数隐含)

相当于执行 MOV AL,[BX+AL]  //而且这里的寄存器是固定不变的,寻址->基址寄存器BX

IN/OUT         I/O端口输入/输出   AL、DX

IN AL,n  //n<=256时  端口地址 直接用立即数表示 00H~FFH

IN AL,DX  //若要表示更大的端口地址,则需要用到数据寄存器DX作为端口地址的存放位

OUT n,AL

二、算术运算指令(会影响标志寄存器中的状态标志)

加减法: 操作符    目的操作数,源操作数;目的操作数=目的操作数@源操作数(有符号补码)

//按定义影响标志寄存器标志位

ADD(加法):ADD DST,SRC

SUB(减法):SUB DST,SRC

ADC(带进位加法):ADC DST,SRC    //DST<-DST+SRC+CF

SBB(带借位减法):SBB DST,SRC     //DST<-DST-SRC-CF

ADD DWORD PTR [BX],02ABC4EFH

加1、减1指令:(有符号补码)

//仅对CF标志位没有影响,假设16位,因为INC加法进位只可能是FFFFH进位,则执行INC之后,结果为0,ZF=1,取代了CF的作用

INC(加一,increase):INC OPR

DEC(减一,decline):DEC OPR 

INC DWORD PTR[BX]   //必须指明存储器操作数的类型

INC AX

INC BYTE PTR[BX+DI+10]

③CMP 比较指令

//按定义影响标志位(减法定义)

CMP OPR1,OPR2

执行OPR1-OPR2 不存数据,只影响标志位,用来判断大小

目的操作数不能是立即数,两操作数不能同时是存储器操作数。(这个①②③都满足)

MUL 无符号乘法

//只影响CF和OF,非定义影响:如果乘积的高半部分为0则CF=0,OF=0,否则均为1

被乘数默认为 AL,AX之一,并且存入AX,DX:AX

MUL BYTE [BX]; (AX)<—(AL)*[BX]//乘数和被乘数等长

MUL WORD [BX[;(DX:AX)<—(AX)*[BX]

MUL AH; (AX)<—(AL)*(AH)

三、BCD码调整指令(会影响标志寄存器中的状态标志)

DAA( 压缩BCD码加法调整指令  bcD Add Ajustment)

//只对AL调整,并且仅OF无定义

1)如果AL的低4位大于9或AF=1,则ADD AL,6 并且AF<-1    //AF是辅助进位,最低四位

2)如果AL的高4位大于9或CF=1,则ADD AL,60H并且CF<-1 //CF是进位

十六进制逢十六进一,可以将加法调整为十进制加法

如:

MOV AL,54H

MOV BL,37H

ADD AL,BL

DAA;DAA只调整AL,所以要将压缩BCD码(8位)放入AL

四、逻辑运算指令(会影响标志寄存器中的状态标志)

①AND,OR,XOR,TEST  按位与,或,异或,按位比较

//CF和OF置0(不产生进位和溢出),AF辅助进位无定义,按定义影响其他

AND DST,SRC

OR DST,SRC

XOR DST,SRC

TEST OPR1,OPR2//只进行 OPR1∧OPR2,不存结果 和CMP一样

NOT 按位取反指令

//不影响标志位

五、移位循环指令

六、控制转移指令

无条件转移

(1)段内相对:

JMP SHORT A1

JMP NEAR PTR A1

(2)段内间接:

JMP OPR //寄存器或存储器操作数

(3)段间直接:
JMP FAR PTR A1

(4)段间间接:

JMP DWORD PTR [OPR]

条件转移

条件相对转移只能是段内短转移 或 段内近转移,8086微处理器只提供短转移方式。

LOOP 循环控制相对转移

//用于已知循环的次数,次数存于计数器CX中

LOOP OPR //相对转移  IP+=8位带符号数,OPR是目标地址

CX<—CX-1  直到CX=0

子程序(过程/函数)的调用 和 返回

//根据子程序的类型确定 段内或 段间,

NEAR 为段内

FAR 为段间

(1)段内相对调用

CALL DST

(2)段内间接调用

CALL DST

(3)段间直接调用

CALL DST

(4)段间间接调用

CALL DST

段内相对和段间直接都是直接给出 子程序名,底层实现是偏移量

而段内间接可以给存储器或寄存器操作数,段间间接只能给存储器操作数

与JMP类似,

与JMP不同的是,它需要将当前IP存入堆栈中,以便返回主程序

(SP<-SP-2        [SP]<-CS)(段间需要)

    SP<-SP-2        [SP]<-IP

⑤子程序 返回

//将堆栈中的IP值存回IP中,如果是段间需要返回CS,具体是段间还是段内 跟调用该指令的子程序类型有关。

RET  (直接返回)

RET N(带参返回,先返回IP(和CS),再返回参数的N个字节) 

中断指令

(1)INT中断指令

INT n ;n为中断类型码

(2)IRET中断返回

(3)INT 21H 系统功能调用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yorelee.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值