【微机原理作业】8086 基本指令和程序结构

一.内容摘要

1.8086基本指令
2.循环结构和分支结构及其程序的实现方法

二.8086基本指令

8086 指令系统包括六大类指令:

  • 数据传送指令 ⭐
  • 算术运算指令 ⭐
  • 逻辑运算和移位指令 ⭐
  • 串操作指令 ⭐
  • 控制转移指令 ⭐
  • 处理器控制指令 ⭐

具体可参考 emu8086 -> help -> documentation and tutorials -> Complete 8086 Instruction Set

1.数据传送指令

功能:将源操作数的内容传送到目的操作数中。

数据传送指令

2.算术运算指令

功能:完成加、减、乘、除运算。

算术运算1
算术运算2

3.逻辑运算和移位指令

功能:(1)完成逻辑“反”、“与"、”或“、”异或“和测试;(2)对数据的移动

逻辑运算和移位指令逻辑运算和移位操作指令的共同点是:

  • 可以按二进制位进行操作;
  • 逻辑运算指令按逻辑门电路的运算规则
  • 逻辑移位指令有左移和右移,移出的位都进入CF标志
  • 因移空位的补充方式不同有多种指令形式
  • 逻辑移位指令中,移动超过1次则用CL寄存器做计数器
  • 执行逻辑操作指令,CF均被清0

4.串操作指令

串指令
串处理指令是针对存储器操作,其的共同点是:

  • 源操作数指针 DS:SI 目的操作数指针 ES:DI
  • 每操作一次SI,DI修改一次,方向由DF控制
  • 串操作指令前通常加上重复前缀,此时,基本操作在满足条件的情况下得到重复,直至完成预设次数。重复操作的退出: CX控制 条件控制(ZF标志)
  • 指令后不带操作数,操作数在此指令前给定。

5.控制转移指令

功能:执行跳转、调子程序、中断服务等。

无条件转移指令
有条件转移指令
![循环控制转移,子程序调用](https://img-blog.csdnimg.cn/20200929000620678.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzQ3MDM4Mw==,size_16,color_FFFFFF,t_70#pic_cente
中断指令

  • 8086程序的执行顺序由代码段寄存器CS和指令指针寄存器IP的值决定。
  • 程序可以按顺序执行,也可以根据情况改变程序的执行顺序。
  • 控制转移指令就是通过改变CS和IP的值来实现程序的转移。

6.处理器控制指令

处理器控制指令

三.程序结构

汇编程序有4种基本结构:

  • 顺序结构 ⭐
  • 分支结构 ⭐
  • 循环结构 ⭐
  • 子程序⭐

1.顺序结构

无分支,无循环,无转移,直线运行到底。例如:

; 
;*****************************************************************************
; @file       add2.asm
; @author     Xiaoxiao
; @date       2020-9-29
; @brief      顺序结构:两个十六进制数相加
; @blog       https://blog.csdn.net/weixin_43470383/article/details/108625923
;*****************************************************************************
;

data segment
    X DW 2020H    ; 被加数
    Y DW 2019H    ; 加数
    RESULT DW ?   ; 分配数存放单元
data ends

stack segment
    dw   128  dup(0)
stack ends

code segment  
    assume cs:code,ds:data ; 段假设
start:
    MOV AX, DATA
    MOV DS, AX
    ; 给除CS以外的其他用到的段的段寄存器赋值

    MOV AX, X
    ADD AX, Y
    MOV RESULT, AX
    ; 处理并存储结果
    
    MOV AH, 4CH
    INT 21H     
    ; 程序运行结束,关闭并返回操作系统   
code ends

end start 

2.分支结构

指令执行过程中,需要进行判断、选择,来决定下一步执行的程序段。例如:

; 
;*****************************************************************************
; @file       pos_neg.asm
; @author     Xiaoxiao
; @date       2020-9-29
; @brief      分支结构:判断MEMS单元数据,将结果存入MEMD单元。
;             若数据>0,结果为1,;若数据<0,结果为-1;若数据=0,结果为0
; @blog       https://blog.csdn.net/weixin_43470383/article/details/108625923
;*****************************************************************************
;

DATA  SEGMENT          ;定义数据段
   MEMS DB 08H         ; 定义一个字节数据
   MEMD DB 0           ; 定义一个字节数据,未赋值
DATA  ENDS             ; 数据段结束

CODE  SEGMENT           ;定义代码段
       ASSUME CS: CODE, DS:DATA     ;段属性说明

START:                 ;这里是程序的入口
    MOV AX , DATA
    MOV DS,  AX     ;初始化DS
    MOV AL, MEMS    ;将MEMS中数据送入AL中
    CMP AL,0        ;(Al)=08H与0进行比较
    JGE NEXT        ;≥0,转到标号NEXT处执行
    MOV AL,-1       ; <0,结果为-1
    JMP DONE        ; 无条件跳转到标号DONE处执行

NEXT: 
    JE DONE         ; =0,跳转到标号DONE处执行
    MOV AL,1        ; >0,结果为1 

DONE: 
    MOV MEMD,AL     ;(AL)内容送入(MEMD)中
    MOV AX, 4C00H
    INT 21H         ;程序结束,返回DOS
CODE  ENDS          ;代码段结束
     END START      ;汇编程序结束,指定程序入口地址

程序中的 JGE NEXT 指令即根据标志位 SF 和 OF 判断是否转移到程序段NEXT,如果SF = OF则转移
CMP AL,0
CMP AL,0点击 single step 下一步执行 CMP AL,0

JGE NEXTJGE NEXT
结果标志位 SF = OF,下一步执行 JGE NEXT

JE DONE
JE DONE
由于 SF = OF,执行 JGE NEXT 之后直接跳转到 NEXT,跳过

MOV AL,-1       ; <0,结果为-1
JMP DONE        ; 无条件跳转到标号DONE处执行

接下来条件判断转移指令 JE DONE 类似,若标志位 ZF = 1,则转移。

3.循环结构

满足一定条件时,重复执行一段程序。
循环控制有3种:

  • 计数法:将循环次数送到 CX 寄存器,循环一次之后,执行 LOOP 指令的时候自动对 CX 寄存器做减1操作。
  • 比较结束条件法:满足比较条件,则结束循环。
  • 设定标志结束法:比如可以设 0FFH 为结束标志。

例程:

; 
;*****************************************************************************
; @file       scan.asm
; @author     Xiaoxiao
; @date       2020-9-29
; @brief      循环结构:在ES中从2000H单元开始存放了10个字符,寻找其中有无"A"
; @blog       https://blog.csdn.net/weixin_43470383/article/details/108625923
;*****************************************************************************
;
data segment
    DATA1 DW 0
    DATA2 DW 0
ends

stack segment
    dw   128  dup(0)
ends

code segment 
    assume cs:code,ds:data,ss:stack
start:

    mov ax, data
    mov ds, ax
    mov es, ax

    MOV DI, 2000H
    MOV BX, DI     ; 偏移地址
    MOV CX, 0AH    ; 10个字符
    MOV AL, 'A'    ; 待检索数据
    CLD            ; (SI、DI)地址自增
    REPNZ SCASB    ; 重复
    JZ FOUND
    MOV DI, 0
    JMP DONE

FOUND:
    DEC DI
    MOV DATA2, DI
    INC DI
    SUB DI, BX     ; 搜索次数
    
DONE:
    MOV DATA1, DI    
    HLT
    
    mov ax, 4c00h 
    int 21h    
ends

end start ; set entry point and stop the assembler.

程序中的 REPNZ SCASB 即根据标志位 CX 和 ZF 判断是否循环进行串搜索 SCASB 指令。每执行一次 SCASB 指令,CX寄存器自动减1,若 CX ≠ 0 且 ZF = 0,搜索操作继续进行。

REPNZ SCASBREPNZ SCASB
点击执行下一步指令 REPNZ SCASB

REPNZ SCASB
REPNZ SCASB
CX ≠ 0 且 ZF = 0,经判断满足继续循环的条件。

REPNZ SCASBREPNZ SCASB
执行完 SCASB 指令,CX内容减1。

REPNZ SCASB
REPNZ SCASB
CX ≠ 0 且 ZF = 0,经判断满足继续循环的条件。如此循环下去,CX 由原来的 000AH 变成 0000H 时,表明搜索完10次,结束循环。循环过程中,如果 CX ≠ 0 且 ZF = 1,表明搜索到“A”,循环也会终止。

4.子程序

  • 将具有特定功能的代码封装成段,即为子程序(过程)。编写子程序能使程序看起来更简洁,方便二次调用。
  • 若与主程序同段,则该子程序的属性为 NEAR,调用主程序时需要将 IP 寄存器的值入栈保存;若子程序与主程序不同段,则属性为 FAR,调用主程序时需要将 CS 和 IP 寄存器的值入栈保存。
  • 子程序的最后一条指令时 RET,执行该指令,返回地址从堆栈中弹出,控制返回到被调用处。

下面是我们老师给出的程序,该程序的作用是判断随机数的奇偶性,分别存储至 odd_number 和 even_number ,并计数。

DATA SEGMENT
    random_number DW 20 DUP(0)
    odd_number    DW 20 DUP(0)
    even_number   DW 20 DUP(0)
    count         DW 0
    odd_count     DW 0
    even_count    DW 0
DATA ENDS

STACK SEGMENT
    DW 128 DUP()
STACK ENDS

CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK

START: 
    MOV AX,DATA
    MOV DS,AX

    MOV  CX,20      ; 20次循环

LOOP_PRO:
    CALL RAND       ; 产生 WORD 随机数,保存在 BX 中
    MOV  SI, count
    INC  count
    SHL  SI, 1
    MOV  random_number[SI], BX
    MOV  AX, BX
    AND  AX, 0x0001
    JZ   EVEN_PRO

ODD_PRO:
    MOV  SI, odd_count
    INC  odd_count
    SHL  SI, 1
    MOV  odd_number[SI], BX
    LOOP LOOP_PRO
    JMP $
    
EVEN_PRO:
    MOV  SI, even_count
    INC  even_count
    SHL  SI, 1
    MOV  even_number[SI], BX
    LOOP LOOP_PRO
    JMP $

RAND PROC
    PUSH CX
    PUSH DX
    PUSH AX
    STI  ; IF置1,允许响应可屏蔽中断
    MOV AH,0 ;读时钟计数器值
    INT 1AH
    MOV BX,DX ;随机数存BX
    POP AX
    POP DX
    POP CX
    RET     
RAND ENDP

CODE ENDS
END START

这段程序中包含1个子程序,RAND 子程序用于产生随机数。
LOOP_PRO 段调用 RAND 子程序,用于传递随机数,并判断奇偶性。
ODD_PRO 段用于处理奇数(存储数据并计数),EVEN_PRO 段用于处理偶数(存储数据并计数)。

参考:《微机原理与接口技术》(第4版)电子工业出版社

  • 13
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不雨_亦潇潇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值