8086汇编学习
代码
移动数据存储位置
;问题:利用变址寄存器,编写一段程序,
;把自1000H单元开始的100个数传送到自1070H开始的存储区(使用8086汇编语言)
; 假设数据已经存储在1000H到10FFH的内存区域中
; 我们将使用SI作为源索引寄存器,DI作为目标索引寄存器
; 计数器将使用CX寄存器,因为我们要传送100个字节
MOV AX,1000H;设置源地址到SI
MOV SI,AX
MOV AX,1070H;设置目的地址到DI
MOV DI,AX
MOV CX,100;设置计数器为100,因为我们传送100个字节
;开始传送循环
REP MOVSB;重复移动字符串操作,SI指向源地址,DI指向目标地址,CX为计数
;至此,数据已经从1000H传送到1070H
累加
; 假设从0500H开始的10个无符号数已经存储在内存中
; 结果的高位将存储在050BH,低位存储在050AH
ORG 100H;程序的起始地址,可以根据实际情况调整
START:
MOV CX,10 ;设置循环计数器为10
XOR AX,AX ;清除AX寄存器,用于累加和
MOV SI,0500H ; 设置源索引寄存器SI为数组的起始地址
SUM_LOOP:
ADD AL,[SI] ;将当前内存单元的值加到AL寄存器(无符号数)
INC SI ;增加SI寄存器,指向下一个内存单元
LOOP SUM_LOOP;循环到CX为0为止
;此时AX中存储着10个无符号数的和
;将AX寄存器的高位和低位分别存储到指定的内存单元
MOV [050AH],AL ;存储和的低位到050AH
MOV [050BH],AH ;存储和的高位到050BH
;程序结束,可以在这里添加退出指令或者返回操作系统的代码
HLT ;停止CPU直到下一个外部中断
END START ;指示汇编器程序的结束
十进制数字相加
; 8086汇编语言程序,用于计算两个BCD码数的和
; 假设第一个BCD码数从0100H开始,第二个BCD码数从0110H开始
; 结果将从0214H开始存储 每个BCD码数长度为10个字节
ORG 100H ; 程序起始地址
MOV SI, 0100H ; 第一个BCD码数的起始地址
MOV DI, 0110H ; 第二个BCD码数的起始地址
MOV BX, 0214H ; 结果存储的起始地址
MOV CX, 10 ; 计数器,用于10个字节的循环
ADD_BCD_LOOP:
MOV AL, [SI] ; 加载第一个BCD码数的当前字节
MOV DL, [DI] ; 加载第二个BCD码数的当前字节
ADD AL, DL ; 将两个BCD码数的当前字节相加
ADC AH, 0 ; 将AH寄存器加载为0,以保存AL相加可能产生的进位
MOV [BX], AL ; 存储相加结果的低字节
INC SI ; 移动到第一个BCD码数的下一个字节
INC DI ; 移动到第二个BCD码数的下一个字节
INC BX ; 移动到结果存储的下一个字节
LOOP ADD_BCD_LOOP ; 循环,直到处理完10个字节
HLT ; 停止程序
END ; 程序结束
HELLO,WORLD
DATA SEGMENT
HELLO DB 'HELLO,WORLD!',0DH,0AH,'$'
DATA ENDS
PROG SEGMENT
ASSUME CS:PROG,DS:DATA
START: MOV AX,DATA
MOV DS,AX
LEA DX,HELLO ;取字符串首地址
MOV AH,9
INT 21H ;显示字符
MOV AH,4CH
INT 21H ;退回DOS
PROG ENDS
END START
应试学习
第一章:微机基础
第四章:汇编程序设计
重点考点:考点2、考点4
1.1汇编语言基本概念
1.汇编语言源程序格式
汇编语言源程序的结构是分段结构形式,一个汇编语言源程序是由若干个段组成的,每个段以SEGMENTS语句开始,以ENDS结束,整个程序的结尾是END语句。
段的四种类型
- 代码段
- 数据段
- 堆栈段
- 附加段
2.代码段结构框:
- 定义段(使用SEGMENTS语句定义)
- 说明物理段和逻辑段的关系,使用一个或者多个ASSUME语句实现
- 装填段寄存器(只装填数据型段寄存器)DS、ES
- 完成所需功能的程序段
- 设置返回DOS的方法
;代码框架
DATA SEGMENTS ;定义数据段起始语句
———— ;定义数据
DATA ENDS ;定义数据段终止语句
CODE SEGMENT ;定义代码段起始语句
ASSUME CS:CODE,DS:DATA;段关系说明
START:MOV AX,DATA;装填相应的段寄存器
MOV DS,AX ;
———— ;完成所需功能的程序段
MOV AH,4CH ;设置返回DOS
INT 21H
CODE ENDS ;定义代码段终止语句
END START ;程序结束
博客园-微机
8086指令
一.数据传送指令
1.通用数据传送指令
MOV;移动 MOV DST,SRC 执行操作:(DST)<-(SRC)
PUSH;压栈 PUSH SRC 执行操作:(SP)<-(SP-2) ((SP)+1,(SP))<-(SRC)
POP;出栈 POP DST 执行操作:(DST)<-((SP+1),(SP)) (SP)<-(SP-2)
XCHG;交换 XCHG OPR1,OPR2 执行操作:(OPR1)<-->(OPR2)
2.累加器专用传送指令
IN;输入 IN AL,PORT(字节) 执行操作:(AL)<-(PORT)(字节) ;长格式
IN AX,PORT(字) 执行操作:(AX)<-(PORT+1,PORT)(字) ;长格式
IN AL,DX(字节) 执行操作:(AL)<-(DX)(字节) ;短格式
IN AX,DX(字) 执行操作:(AX)<-(DX+1,DX)(字) ;短格式
OUT;输出 OUT PORT(字节),AL 执行操作:(PORT)(字节)<-(AL) ;长格式
OUT PORT(字),AX 执行操作:(PORT+1,PORT)(字)<-(AX) ;长格式
OUT DX(字节),AL 执行操作:(DX)(字节)<-(AL) ;短格式
OUT DX(字),AX 执行操作:(DX+1,DX)(字)<-(AX) ;短格式
在IBM-PC机里,外部设备最多可有65536个I/O端口,端口(即外设的端口地址)为0000FFFFH.其中前256个端口(0FFH)可以直接在指令中指定,这就是长格式中的PORT,此时机器指令用二个字节表示,第二个字节就是端口号.所以用长格式时可以在指定中直接指定端口号,但只限于前256个端口.当端口号>=256时,只能使用短格式,此时,必须先把端口号放到DX寄存器中(端口号可以从0000到0FFFFH),然后再用IN或OUT指令来 传送信息.
XLAT;换码指令 XLAT OPR;(或者 XLAT) 执行操作:(AL)<-((BX)+(AL))
3.有效地址送寄存器指令
LEA;(Load effective address)有效地址送寄存器 LEA REG,SRC 执行操作:(REG)<-(SRC);指令把源操作数的有效地址送到指定的寄存器中
LDS;(Load DS with Pointer)指针送寄存器和DS指令 LDS REG,SRC 执行操作:(REG)<-(SRC) (DS)<-(SRC+2) ;把源操作数指定的4个相继字节送到由指令指定的寄存器及DS寄存器中,该指令常指定SI寄存器
LES;(Load ES with Pointer)指针送寄存器和ES指令 LES REG,SRC 执行操作:(REG)<-(SRC) (ES)<-(SRC+2) ;把源操作数指定的4个相继字节送到由指令指定的寄存器及ES寄存器中,该指令常指定DI寄存器
4.标志寄存器传送指令
LAHF;(Load AH with flags)标志送AH LAHF 执行操作:(AH)<-(PWS的低字节);
SAHF;(Store AH into flags)AH送标志寄存器 SAHF 执行操作:(PWS的低字节)<-(AH);
PUSHF;(push the flags)标志进栈 PUSHF 执行操作:((SP)->(SP-2)) ((SP+1),(SP))<-(PSW) ;
POPF;(pop the flags)标志出栈 POPF 执行操作: (PSW)<-((SP+1),(SP)) ((SP)->(SP+2)) ;
二、算术指令
1.加法指令
ADD;(add)加法 ADD DST,SRC 执行操作:(DST)<-(DST)+(SRC);
ADC;(add with carry)带进位加法 ADC DST,SRC 执行操作:(DST)<-(DST)+(SRC)+CF;
INC;(increment)加1 INC OPR 执行操作:(OPR)<-(OPR)+1;
2.减法指令
SUB;(subtract)减法 SUB DST, SRC 执行操作:(DST)<-(DST)-(SRC);
SBB;(subtract with borrow)带借位减法 SBB DST, SRC 执行操作:(DST)<-(DST)-(SRC)-CF;
DEC;(decrement)减1 DEC OPR 执行操作:(OPR)<-(OPR)-1;
CMP;(compare)比较 CMP OPR1,OPR2 执行操作:(OPR1)-(OPR2)-1;
该指令与SUB指令一样执行减法操作,但不保存结果,只是根据结果设置条件标志西半球.
NEG;(negate)求补码 NEG OPR 执行操作:(OPR)<--(OPR);
3.乘法指令
MUL;(unsigned multiple)无符号数乘法 MUL SRC 执行操作:(AX)<--(AL)*(SRC);字节操作数
执行操作:(DX,AX)<--(AX)*(SRC);字操作数
IMUL;(signed multiple)带符号数乘法 IMUL SRC 执行操作:与MUL相同,但必须是带符号数
4.除法指令
DIV;(unsigned divide)无符号数除法 DIV SRC 执行操作:(AL)<--(AX)/(SRC)的商 (AH)<--(AX)/(SRC)的余数;字节操作数
执行操作:(AX)<--(DX,AX)/(SRC)的商 (DX)<--(DX,AX)/(SRC)的余数;字操作数
IDIV;(signed divide)带符号数除法 IDIV SRC 执行操作:与DIV相同,但必须是带符号数
CBW;(convert byte to word)字节转字 CBW 执行操作:AL的内容符号扩展到AH.即如果(AL)的最高有效位为0,则(AH)=00;如(AL)的最高有效位为1,则(AH)=0FFH
CWD;(convert word to double)字转双字CWD 执行操作:AX的内容符号扩展到DX.即如果(AX)的最高有效位为0,则(DX)=0;否则(DX)=0FFFFH
三、逻辑指令
1.逻辑运算指令
AND;(and)逻辑与 ADD DST,SRC 执行操作:(DST)<-(DST)and(SRC);
OR;(or)逻辑或 OR DST,SRC 执行操作:(DST)<-(DST)or(SRC);
NOT;(not)逻辑非 NOT OPR 执行操作:(OPR)<-非(OPR);
XOR;(exclusive or)逻辑异或 XOR DST,SRC 执行操作:(DST)<-(DST)xor(SRC);
TEST;(test)测试入标志位 TEST OPR1,OPR2 执行操作:如下图
2.移位指令
SHL;(shift logical left)逻辑左移 格式: SHL OPR,CNT(其余的类似)
SAL;(shift arithmetic left)算术左移
SHR;(shift logical righr)逻辑右移
SAR;(shift arithmetic right)算术右移
ROL; (rotate left)循环左移
ROR; (rotate right)循环右移
RCL; (rotate left through carry)带进位循环左移
RCR; (rotate right through carry)带进位循环右移
其中OPR可以是除立即数以外的任何寻址方式.移位次数由CNT决定,CNT可以是1或CL.
循环移位指令可以改变操作数中所有位的位置;移位指令则常常用来做乘以2除以2操作.其中算术移位指令适用于带符号数运算,SAL用来乘2,SAR用来除以2;而逻辑移位指令则用来无符号数运算,SHL用来乘2,SHR用来除以2
四、串处理指令
1.与REP相配合的MOVS、STOS和LODS指令
REP;REP重复串操作直到(CX)=0为上 REP string primitive(String Primitive可为MOVS,LODS或STOS指令) 执行操作:1)如(CX)=0则退出REP,否则往下执行.
2)(CX)<-(CX)-1
3)执行其中的串操作
4)重复1)~3)
MOVS; 串传送指令 MOVS ES:BYTE PTR[DI],DS:[SI] 执行的操作:1)((DI))<-((SI)) ;应在操作数中表明是字还是字节操作(此处的DST和SRC举例实际说明了)
2)字节操作:(SI)<-(SI)+(或-)1,(DI)<-(DI)+(或-)1当方向标志DF=0时用+,当方向标志DF=1时用-
3)字操作:(SI)<-(SI)+(或-)2,(DI)<-(DI)+(或-)2 当方向标志DF=0时用+,当方向标志DF=1时用-
MOVSB(字节) DST,SRC
MOVSW(字) DST,SRC
CLD;(Clear direction flag) 该指令使DF=0,在执行串操作指令时可使地址自动增量;
STD;(Set direction flag) 该指令使DF=1,在执行串操作指令时可使地址自动减量.
STOS; 存入串指令 STOS DST
STOSB DST 字节操作:((DI))<-(AL),(DI)<-(DI)+-1
STOSW DST 字操作: ((DI))<-(AX),(DI)<-(DI)+-2
该指令把AL或AX的内容存入由(DI)指定的附加段的某单元中,并根据DF的值及数据类型修改DI的内容,当它与REP联用时,可把AL或AX的内容存入一个长度为(CX)的缓冲区中.
LODS; 从串取指令 LODS SRC
LODSB SRC 字节操作:(AL)<-((SI)),(SI)<-(SI)+-1
LODSW SRC 字操作: (AX)<-((SI)),(SI)<-(SI)+-2
该指令把由(SI)指定的数据段中某单元的内容送到AL或AX中,并根据方向标志及数据类型修改SI的内容.指令允许使用段跨越前缀来指定非数据段的存储区.该指令也不影响条件码.一般说来,该指令不和REP联用.有时缓冲区中的一串字符需要逐次取出来测试时,可使用本指令.
2.与REPE/REPZ和REPNZ/REPNE联合工作的CMPS和SCAS指令
REPE/REPZ 当相等/为零时重复串操作 REPE(或REPZ) String Primitive 其中String Primitive可为CMPS或SCAS指令.
执行的操作:1)如(CX)=0或ZF=0(即某次比较的结果两个操作数不等)时退出,否则往下执行
2)(CX)<-(CX)-1
3)执行其后的串指令
4)重复1)~3)
REPNE/REPNZ 当不相等/不为零时重复串操作 REPNE(或REPNZ) String Primitive 其中String Primitive可为CMPS或SCAS指令.
执行的操作:除退出条件(CX=0)或ZF=1外,其他操作与REPE完全相同.
CMPS 串比较指令 CMP SRC,DST 执行的操作: 1)((SI))-((DI))
CMPSB 2)字节操作:(SI)<-(SI)+-1,(DI)<-(DI)+-1
CMPSW 2)字操作: (SI)<-(SI)+-2,(DI)<-(DI)+-2
指令把由(SI)指向的数据段中的一个字(或字节)与由(DI)指向的附加段中的一个字(或字节)相减,但不保存结果,只根据结果设置条件码,指令的其它特性和MOVS指令的规定相同.
SCAS 串扫描指令 SCAS DST 执行的操作:
SCASB 字节操作:(AL)-((DI)),(DI)<-(DI)+-1
SCASW 字操作: (AL)-((DI)),(DI)<-(DI)+-2
该指令把AL(或AX)的内容与由(DI)指定的在附加段中的一个字节(或字)进行比较,并不保存结果,只根据结果置条件码.指令的其他特性和MOVS的规定相同.
五、控制转移指令
1.无条件转移指令
JMP(jmp) 跳转指令
-
- 段内直接短转移 JMP SHORT OPR 执行的操作: (IP)<-(IP)+8位位移量
- 段内直接近转移 JMP NEAR PTR OPR 执行的操作:(IP)<-(IP)+16位位移量
- 段内间接转移 JMP WORD PTR OPR 执行的操作:(IP)<-(EA)
- 段间直接(远)转移 JMP FAR PTR OPR 执行的操作:(IP)<-OPR的段内偏移地址 (CS)<-OPR所在段的段地址
- 段间间接转移 JMP DWORD PTR OPR 执行的操作:(IP)<-(EA) (CS)<-(EA+2)
2.条件转移指令
1)根据单个条件标志的设置情况转移
JZ(jump if zero) 结果为0则跳转 JZ OPR 测试条件:ZF=1,跳转
JE(jump if equal) 结果相等则跳转 JE OPR 测试条件:ZF=1,跳转
JNZ(jump if not zero) 结果不为0则跳转 JNZ OPR 测试条件:ZF=0,跳转
JNE(jump if not equal) 结果不相等则跳转 JNE OPR 测试条件:ZF=0,跳转
JS(jump if sign) 结果为负则跳转 JS OPR 测试条件:SF=1,跳转
JNS(jump if not sign) 结果不为负则跳转 JNS OPR 测试条件:SF=0,跳转
JO(jump if overflow) 结果溢出则跳转 JO OPR 测试条件:OF=1,跳转
JNO(jump if not overflow) 结果不溢出则跳转 JNO OPR 测试条件:OF=0,跳转
JP(jump if parity) 奇偶位为1则跳转 JP OPR 测试条件:PF=1,跳转
JNP(jump if not parity 奇偶位不为1 JNP OPR 测试条件:PF=0,跳转
JPE(jump parity even) 奇偶位为1则跳转 JPE OPR 测试条件:PF=1,跳转
JPO(jump parity odd) 奇偶位不为1 JPO OPR 测试条件:PF=0,跳转
JB/JNAE/JC 低于,或者不高于或等于,或进位位为1则转移
JNB/JAE/JNC 不低于,或者高于或者等于,或进位位为0则转移
寄存器
AX:数据累加器:算术运算中的主要寄存器, 在乘除运算中用来指定被除数和被除数, 也是乘, 除,运算后积和商的默认存储单元. 另外I/O指令均使用该寄存器与I/O设备传送信息
BX:基址寄存器:指令寻址时常用做基址寄存器. 存入偏移量或偏移量的构成成分
CX:计算寄存器:在循环指令操作或串处理指令中隐含计数
DX:数据寄存器:在双字节长运算是, 与AX构成32位操作数, DX为高16位. 在某些I/O指令中, DX被用来存放端口地址
CS:代码段:存放当前程序的指令代码
DS:数据段:存放程序所涉及的源数据或结果
SS:堆栈段:以”先入后出”为原则的数据区
ES:附加段:辅助数据区, 存放串或其他数据
SP:堆栈指针寄存器:始终只是栈顶的位置, 与SS寄存器一起组成栈顶数据的物理地址
BP:基址指针寄存器:系统默认其指向堆栈中某一单元, 即提供栈中该单元的偏移量. 加段前缀后, BP可作非堆栈段的地址指针
SI:源变址寄存器:与DS联用, 指示数据段中某操作的偏移量. 在做串处理时, SI指示源操作数地址, 并有自动增量或自动减量的功能. 变址寻址时, SI与某一位移量共同构成操作数的偏移量
DI:目的变址寄存器:与DS联用, 指示数据段中某操作数的偏移量, 或与某一位移量共同构成操作数的偏移量. 串处理操作时, DI指示附加段中目的地址, 并有自动增量或减量的功能
IP:指令指针寄存器:它始终指向当前将要执行指令在代码段中存放的偏移量
FR:控制标志位:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· c# 半导体/led行业 晶圆片WaferMap实现 map图实现入门篇
· 易语言 —— 开山篇