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

img

1.1汇编语言基本概念

1.汇编语言源程序格式

​ 汇编语言源程序的结构是分段结构形式,一个汇编语言源程序是由若干个段组成的,每个段以SEGMENTS语句开始,以ENDS结束,整个程序的结尾是END语句。

段的四种类型

  • 代码段
  • 数据段
  • 堆栈段
  • 附加段

2.代码段结构框:

  1. 定义段(使用SEGMENTS语句定义)
  2. 说明物理段和逻辑段的关系,使用一个或者多个ASSUME语句实现
  3. 装填段寄存器(只装填数据型段寄存器)DS、ES
  4. 完成所需功能的程序段
  5. 设置返回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指令

img

img

一.数据传送指令

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);

img

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

img

三、逻辑指令

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 执行操作:如下图

img

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) 跳转指令

    1. 段内直接短转移 JMP SHORT OPR   执行的操作: (IP)<-(IP)+8位位移量
    2. 段内直接近转移 JMP NEAR PTR OPR  执行的操作:(IP)<-(IP)+16位位移量
    3. 段内间接转移 JMP WORD PTR OPR  执行的操作:(IP)<-(EA)
    4. 段间直接(远)转移 JMP FAR PTR OPR  执行的操作:(IP)<-OPR的段内偏移地址 (CS)<-OPR所在段的段地址
    5. 段间间接转移 JMP DWORD PTR OPR 执行的操作:(IP)<-(EA) (CS)<-(EA+2)

img

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则转移

img

img

img

寄存器

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:控制标志位:

img

img

posted @   燊楽  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· c# 半导体/led行业 晶圆片WaferMap实现 map图实现入门篇
· 易语言 —— 开山篇
点击右上角即可分享
微信分享提示