微机原理实验四、编写程序,统计寄存器AX中二进制数位“0”的个数,结果以十进制数形式显示到屏幕上
; 功能: 统计寄存器AX中二进制数位“0”的个数,结果以十进制数形式显示到屏幕上
; 思路
; 将二进制数逐位右移,然后判断最低位是否是 0,
; 如果是则计数器 BX 加 1。循环 8 次后,BX 中存储的就是二进制数中 0 的个数。
; 最后将 BX 的值转换成 ASCII 码,并通过 INT 21H 显示出来。
; 调试结果:
; input:10110101
; output: 3
二、 LOOP 循环指令
LOOP
指令是 x86 汇编语言中的一个循环控制指令,用于实现循环结构。它的基本作用是根据 CX
寄存器中的值来控制循环的执行次数。
下面是 LOOP
指令的基本语法:
LOOP destination
destination
是循环体的目标标号,指示程序应该在循环体中的哪个位置继续执行。
LOOP
指令的工作原理如下:
- 检查
CX
寄存器的值。 - 如果
CX
寄存器中的值不为零,则将其减一。 - 如果
CX
寄存器中的值仍然不为零,则跳转到destination
标号处继续执行,否则继续执行下一条指令。
举例来说,假设我们要编写一个循环,使某段代码重复执行 5 次:
MOV CX, 5 ; 将循环次数 5 存入 CX 寄存器
LOOP_START: ; 循环开始标号
; 在这里编写循环体的代码
; 这段代码会重复执行 5 次
LOOP LOOP_START ; 跳回到 LOOP_START 标号处执行循环
在这个例子中,LOOP_START
标号是循环体的起始位置。MOV CX, 5
将循环次数 5 存入 CX
寄存器。然后,LOOP LOOP_START
指令会检查 CX
寄存器的值,如果 CX
寄存器中的值不为零,则将其减一,并跳回到 LOOP_START
标号处继续执行循环体中的代码。这样,循环体中的代码会重复执行 5 次,直到 CX
寄存器的值为零,循环结束。
三、 DIV 除法指令
DIV
指令用于无符号整数
的除法操作,它将存储在双字寄存器 DX:AX
中的数值除以操作数,并将商存储在 AX
中,余数存储在 DX
中。以下是 DIV
指令的使用方法和相关寄存器的作用:
-
DIV
指令:执行除法操作,将DX:AX
的值除以操作数。- 格式:
DIV operand
- 操作数:除数,可以是寄存器、内存位置或立即数。
- 功能:将
DX:AX
的值除以操作数,并将商存储在AX
中,余数存储在DX
中。 - 注意:被除数的位数是受限的,取决于操作数的位数。例如,如果操作数是8位的,那么被除数必须是16位的。
- 格式:
-
DX:AX
寄存器对:AX
寄存器:存储除法的被除数和商。DX
寄存器:存储除法的余数。
-
使用方法:
- 在执行
DIV
指令之前,需要确保DX
寄存器中的值为被除数的高 16 位,AX
寄存器中的值为被除数的低 16 位。 DIV
指令执行后,商将存储在AX
中,余数将存储在DX
中。
- 在执行
四、 汇编实现程序完整代码
实现输出:
; @Description: 统计寄存器AX中二进制数位“0”的个数,结果以十进制数形式显示到屏幕上
;* @Version: 1.0
;* @Autor: Huining Li777
; @ 思路:
; 将二进制数逐位右移,然后判断最低位是否是 0,
; 如果是则计数器 BX 加 1。循环 8 次后,BX 中存储的就是二进制数中 0 的个数。
; 最后将 BX 的值转换成 ASCII 码,并通过 INT 21H 显示出来。
; @ 调试结果:
; input:10110101
; output: 3
DATA SEGMENT
NUM DW 0B5H;
DATA ENDS
STACK SEGMENT
DW 100H DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STACK
START:
MOV AX, DATA ; 将数据段的段地址加载到 AX 寄存器中
MOV DS, AX ; 将 AX 寄存器中的数据段地址设置到 DS 寄存器,以便程序能够访问数据段中的数据
MOV AX, NUM ; 将NUM的值加载到AL寄存器中
MOV CX, 8 ; CX 计数器,循环 8 次
MOV BX, 0 ; BX 用于计数 0 的个数
LOOP1:
SHR AX, 1 ; 右移 AX 的最低位
JC SKIP1 ; 如果最低位是 1,跳过 SKIP1
INC BX ; 最低位是 0,BX 加 1
SKIP1:
LOOP LOOP1 ; 循环 8 次
; 将 BX 转换成十进制数
MOV CX, 10 ; CX 存储除数
MOV DX, 0 ; DX 存储余数
MOV AX, BX ; AX 存储被除数
DIV1:
DIV CX ; AX 除以 CX,商存入 AX,余数存入 DX
PUSH DX ; 将余数压入栈中
CMP AX, 0 ; 如果商为 0,跳出循环
JNE DIV1
MOV AH, 2 ; 显示字符
PRINT:
POP DX ; 弹出栈顶元素
ADD DL, '0' ; 将余数转换成 ASCII 码
INT 21H
CMP SP, 0 ; 如果栈为空,跳出循环
JNE PRINT
; 输出结果后换行
MOV DL, 10 ; 换行符
MOV AH, 2 ; 显示字符
INT 21H
; Exit program
MOV AH, 4CH
INT 21H
CODE ENDS
END START
上面代码的码制转换中有:
DIV1
的使用:
MOV AX, BX
将BX
中的值复制到AX
,作为被除数。MOV CX, 10
将 10 存储在CX
中,作为除数。MOV DX, 0
用于存储余数,初始化为0。DIV CX
执行除法操作,将DX:AX
的值除以CX
,商存储在AX
中,余数存储在DX
中。PUSH DX
将余数压入栈中,以便后续将余数转换为 ASCII 码。CMP AX, 0
检查商是否为0,如果不为0,则继续循环。JNE DIV1
如果商不为0,则继续执行除法操作,直到商为0。POP DX
弹出栈顶元素,即余数。ADD DL, '0'
将余数转换成 ASCII 码。INT 21H
显示字符。CMP SP, 0
检查栈是否为空。JNE PRINT
如果栈不为空,则继续循环,继续输出余数。