0
点赞
收藏
分享

微信扫一扫

汇编语言程序设计之统计元素个数


汇编语言程序设计之统计元素个数

  • ​​前言​​
  • ​​题目描述​​
  • ​​题目分析​​
  • ​​参考代码​​
  • ​​程序使用指令详解​​
  • ​​六大标志位​​
  • ​​CF——进位标志位​​
  • ​​PF——奇偶标志位​​
  • ​​AF——辅助进位标志位​​
  • ​​ZF——零标志位​​
  • ​​SF——符号标志位​​
  • ​​OF——溢出标志位​​
  • ​​XOR指令​​
  • ​​OR指令​​
  • ​​LEA——取偏移地址指令​​
  • ​​LODSB——串装入指令​​
  • ​​条件转移指令​​
  • ​​程序执行过程详解​​

前言

统计元素个数这样的问题,思路其实很简单,用高级语言来实现的话,几行代码就可以搞定,但是如果要用汇编语言来实现的话,代码量会稍微多一些,但解题思路其实是一样的。

题目描述

在内存数据段处存放有10个8位带符号数,其首地址为MEM,试统计其中正元素、负元素和零元素的个数,并分别将个数存入PLUS、MINUS、ZERO这三个单元中。

题目分析

为了实现上述计数功能:

  1. 可先将PLUS、MINUS、ZERO这三个单元清零
  2. 然后将数据段中的数据依次放入AL中
  3. 利用OR指令让操作数自身相或
  4. 再用条件转移指令测试该数是正数、负数还是零
  5. 最后分别在对应的单元中计数。

参考代码

DATA   SEGMENT
MEM DB 05H,00H,83H,12H,0FAH,77H,0CDH,9BH, 66H,00H
PLUS DB 1 DUP(?)
MINUS DB 1 DUP(?)
ZERO DB 1 DUP(?)
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
XOR AL,AL ;AL清零
MOV PLUS,AL ;PLUS清零
MOV MINUS,AL ;MINUS清零
MOV ZERO,AL ;ZERO清零
LEA SI,MEM ;数据首地址送入SI
MOV CL,10 ;数据长度送入CL
CLD
CHECK: LODSB ;AL←[DS:SI]即取一个数到AL
OR AL,AL ;操作数自身相“或”,AL内容不变,仅影响标志位
JS X1 ;若为负数,即SF=1时转X1
JZ X2 ;若为零,即ZF=0时转X2
INC PLUS ;否则为正,PLUS单元加1
JMP NEXT
X1: INC MINUS ;MINUS单元加1
JMP NEXT
X2: INC ZERO ;ZERO单元加1
NEXT: DEC CL ;数据长度CL加1
JNZ CHECK ;若CL的值不为0即ZF=0则转CHECK
MOV AH,4CH
INT 21H
CODE ENDS
END START

程序使用指令详解

  • ​​MOV指令的使用详解​​

六大标志位

在本程序中,使用OR指令、DEC指令或INC指令时,当条件满足时会使状态标志位发生改变

因此我们需要牢牢记住以下六个状态标志位发生改变的条件

CF——进位标志位

当进行加(减)法运算时,若最高位向前有进(借)位,则CF=1,否则CF=0

PF——奇偶标志位

当运算结果的低8位中1的个数为偶数时PF=1,为奇数时PF=0

AF——辅助进位标志位

在加(减)法操作中,D3向D4有进位(借位)时,AF=1,否则AF=0

DAA指令和DAS指令测试这个标志位,以便在BCD加法或减法之后调整AL中的值

ZF——零标志位

当运算结果为零时,ZF=1,否则ZF=0

SF——符号标志位

当运算结果的最高位为1时SF=1,否则SF=0

OF——溢出标志位

当算数运算的结果超出了带符号数的范围,即溢出时OF=1,否则OF=0

XOR指令

XOR是逻辑运算中的异或指令,其格式为:

XOR OPRD1,OPRD2

两个相同的操作数相异或,能使操作数置零:

XOR AX,AX ;AX 0,使AX清零

OR指令

OR是逻辑运算中的或指令,其格式为:

OR OPRD1,OPRD2

OR指令有下面三种应用:

  • 实现两操作数按位相“或”的运算

OR AX,[DI]

  • 使某些位不变,某些位置“1”

OR CL,0FH

  • 在不改变操作数的 情况下使OF=CF=0

OR AX,AX

LEA——取偏移地址指令

LEA能将存储器操作数的16位偏移地址取出送目标寄存器

当程序中用符号地址表示内存偏移地址时,须使用该指令

指令格式:

LEA REG,MEM

源操作数必须是一个存储器操作数,目标操作数通常是间址寄存器

汇编语言程序设计之统计元素个数_指令

LODSB——串装入指令

串装入指令有3种格式:

LODS OPRD

LODSB

LODSW

该用于将内存某个区域的数据串依次装入累加器,以便显示或输出到接口,指令执行后会将[DS:SI]里的值送入AX或AL

条件转移指令

汇编语言程序设计之统计元素个数_指令_02

程序执行过程详解

进入断点调试:

汇编语言程序设计之统计元素个数_指令_03


核心代码从清零3个计数单元开始,首先来看一下初始状态:

汇编语言程序设计之统计元素个数_指令_04


要判断的10个值存放在数据段ds里,紧接着的是PLUS、MINUS、ZERO这三个单元,巧的是这三个单元的初始值为0,为了保险起见,我们需要用代码再给他们清零。首先让AL变为0,AL是AX的低八位:

汇编语言程序设计之统计元素个数_MASM_05


接着把PLUS、MINUS、ZERO这三个单元清零:

汇编语言程序设计之统计元素个数_编程语言_06


下一步是把要比较的数据取出来,用LEA把数据的偏移地址拿到:

汇编语言程序设计之统计元素个数_汇编_07


这里因为偏移地址就是0000,所以没有变化,但其实已经取到了偏移地址

接着就进入了程序的主要部分CHECK。

通过LODSB指令将数据取到AL中,于此同时si指向下一个数据:

汇编语言程序设计之统计元素个数_指令_08


使用OR指令让操作数AL与自身相或,注意看标志位的变化:

汇编语言程序设计之统计元素个数_MASM_09


操作数05H与自身相或:

  • 结果无进位:CF=0
  • OR不改变操作数,即结果不为零:ZF=0
  • 05H是正数,第一位为0,所以:SF=0
  • OR运算无溢出,故:OF=0
  • 05H的二进制表示为00000101B,即1的个数为偶数,故:PF=1
  • OR运算无进位或借位,故:AF=0

因为SF=1,所以JS的条件不成立,程序往下执行:

汇编语言程序设计之统计元素个数_指令_10

因为ZF=0,所以JZ的转移条件不成立,程序继续执行,不跳转,PLUS加1:

汇编语言程序设计之统计元素个数_编程语言_11


此时经过一个无条件转移指令JMP,程序跳转至NEXT处执行:

汇编语言程序设计之统计元素个数_汇编_12


外循环次数减1,因为CL没有减到0,运算结果不为0故ZF=0,条件成立,程序跳转到CHECK处执行:

汇编语言程序设计之统计元素个数_汇编_13


如此往复循环,直至10个数全部遍历结束为止


举报

相关推荐

0 条评论