当前位置: 代码迷 >> 综合 >> 【微机原理作业】8086 基本指令和程序结构
  详细解决方案

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

热度:77   发布时间:2024-02-24 16:06:02.0

一.内容摘要

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     Huo Xiaoxiao
; @number     201821030208
; @date       2020-9-29
; @brief      顺序结构:两个十六进制数相加
; @blog       https://blog.csdn.net/weixin_43470383/article/details/108625923
;*****************************************************************************
;data segmentX DW 2020H    ; 被加数Y DW 2019H    ; 加数RESULT DW ?   ; 分配数存放单元
data endsstack segmentdw   128  dup(0)
stack endscode segment  assume cs:code,ds:data ; 段假设
start:MOV AX, DATAMOV DS, AX; 给除CS以外的其他用到的段的段寄存器赋值MOV AX, XADD AX, YMOV RESULT, AX; 处理并存储结果MOV AH, 4CHINT 21H     ; 程序运行结束,关闭并返回操作系统   
code endsend start 

2.分支结构

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

; 
;*****************************************************************************
; @file       pos_neg.asm
; @author     Huo Xiaoxiao
; @number     201821030208
; @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 , DATAMOV DS,  AX     ;初始化DSMOV AL, MEMS    ;将MEMS中数据送入AL中CMP AL,0        ;(Al)=08H与0进行比较JGE NEXT        ;≥0,转到标号NEXT处执行MOV AL,-1       ; <0,结果为-1JMP DONE        ; 无条件跳转到标号DONE处执行NEXT: JE DONE         ; =0,跳转到标号DONE处执行MOV AL,1        ; >0,结果为1 DONE: MOV MEMD,AL     ;(AL)内容送入(MEMD)中MOV AX, 4C00HINT 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     Huo Xiaoxiao
; @number     201821030208
; @date       2020-9-29
; @brief      循环结构:在ES中从2000H单元开始存放了10个字符,寻找其中有无"A"
; @blog       https://blog.csdn.net/weixin_43470383/article/details/108625923
;*****************************************************************************
;
data segmentDATA1 DW 0DATA2 DW 0
endsstack segmentdw   128  dup(0)
endscode segment assume cs:code,ds:data,ss:stack
start:mov ax, datamov ds, axmov es, axMOV DI, 2000HMOV BX, DI     ; 偏移地址MOV CX, 0AH    ; 10个字符MOV AL, 'A'    ; 待检索数据CLD            ; (SI、DI)地址自增REPNZ SCASB    ; 重复JZ FOUNDMOV DI, 0JMP DONEFOUND:DEC DIMOV DATA2, DIINC DISUB DI, BX     ; 搜索次数DONE:MOV DATA1, DI    HLTmov ax, 4c00h int 21h    
endsend start ; set entry point and stop the assembler.

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

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

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

REPNZ SCASBREPNZ SCASB
执行完 SCAS 指令,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 SEGMENTrandom_number DW 20 DUP(0)odd_number    DW 20 DUP(0)even_number   DW 20 DUP(0)count         DW 0odd_count     DW 0even_count    DW 0
DATA ENDSSTACK SEGMENTDW 128 DUP()
STACK ENDSCODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACKSTART: MOV AX,DATAMOV DS,AXMOV  CX,20      ; 20次循环LOOP_PRO:CALL RAND       ; 产生 WORD 随机数,保存在 BX 中MOV  SI, countINC  countSHL  SI, 1MOV  random_number[SI], BXMOV  AX, BXAND  AX, 0x0001JZ   EVEN_PROODD_PRO:MOV  SI, odd_countINC  odd_countSHL  SI, 1MOV  odd_number[SI], BXLOOP LOOP_PROJMP $EVEN_PRO:MOV  SI, even_countINC  even_countSHL  SI, 1MOV  even_number[SI], BXLOOP LOOP_PROJMP $RAND PROCPUSH CXPUSH DXPUSH AXSTI  ; IF置1,允许响应可屏蔽中断MOV AH,0 ;读时钟计数器值INT 1AHMOV BX,DX ;随机数存BXPOP AXPOP DXPOP CXRET     
RAND ENDPCODE ENDS
END START

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

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