博主是个大笨比,只会阿巴阿巴阿巴
题目
已知数据定义如下,编程统计str字节单元中奇数的个数,并把数存入result单元
Data SEGMENT
str DB 51,30,43,107,89,90,200,27,70,66
result DB ?
Data ENDS
注意:由于博主的电脑如果使用 str
作为变量名称会报错:
errorA2085 instruction or register not accepted in current CPU mode
指令或寄存器在当前CPU模式下不被接受
若使用其他变量名如 Abits
则编译通过,博主也并没有查到解决办法,如果有人知道解决方法,请评论说明,我在这里表示感谢 Thanks♪(・ω・)ノ 。
指令 | 意思 |
---|---|
LEA (指令) | 将源操作数的有效偏移地址传递给寄存器 |
offect(操作符) | 取出标号或变量在段内的偏移地址 (有时 与LEA 所表达的效果相同) |
SHR | 逻辑右移 |
CWB | 字节扩展指令,将AL扩展至AH,如果D7 = 0 则 AH 为 0 否则 AX 为 0FFH |
JNB(或者 JAE) | 如果 CF = 0 则 跳转 |
test | 用来判断某位是否为0 ,若ZF为1 则表明 某位为0 否则某位就是1 |
JZ | 若 ZF = 1 则跳转 |
DIV | 格式为 DIV SRC 如果SRC为字节 默认被除数在AX中,得到的8位商在AL中 余数在AH中 |
CMP | 比较两数字是否相同,只影响标志位,不回传结果,如果相同 则ZF = 0 |
思路一(通过移位实现)
仔细观察这里面的数
- 奇数:51,43,107,89,27
- 偶数:30,90,200,70,66
奇数二进制(基2码 ):
51: 0011 0011
43: 0010 1011
107:0110 1011
89: 0101 1001
27: 0001 1011
偶数二进制:
30: 0001 1110
90 0101 1010
200 1100 1000
70 0100 0110
66 0100 0010
奇数的最后一位都是 1 如果我们将其移动到CF中并判断其值 变可以分辨其是奇数还是偶数
Data SEGMENT
Abits DB 51,30,43,107,89,90,200,27,70,66
RESULT DB ?
Data ENDS
Code SEGMENT
ASSUME CS:Code,DS:Data
Start:
MOV AX,Data
MOV DS,AX
;================================================================
LEA BX,Abits ;取出Abits的有效偏移地址
MOV RESULT,0 ;将RESULT的初始值赋值为0
MOV CX,10 ;循环次数为10
Judge:
MOV AH,0 ;将AX的最高位赋值为0 (这里其实就是为了数据的美观,好看)
MOV AL,[BX] ;读取Abits中的值 赋给 al
INC BX ;使BX内容+1 地址内容 +1
SHR AX,1 ;逻辑左移
JNB Next ;判断是否为 0 如果是则开始下一次循环,否则就向下执行
INC RESULT ;使RESULT的值 +1
;================================================================
Next:
LOOP Judge ;循环
Exit:
MOV AH,0 ;将AX的最高位赋值为0 (这里其实就是为了数据的美观,好看)
MOV AL,RESULT;将RESULT中的值赋值给AL (其实就是可以在DEBUG中更容易看到得数)
MOV AH,4CH
INT 21H
Code ENDS
END Start
思路二(利用Test指令的特性)
Data SEGMENT
Abits DB 51,30,43,107,89,90,200,27,70,66
RESULT DB ?
Data ENDS
Code SEGMENT
ASSUME CS:Code,DS:Data
Start:
MOV AX,Data
MOV DS,AX
;================================================================
MOV BL,0 ;将BL的值清0
LEA SI,ABITS ;将SI寄存器的值 赋值为 变量的有效地址
MOV CX,10 ;循环次数为10
Judge:
MOV AL,[SI] ;将地址中的值赋值给al寄存器
TEST AL,01H ;test 指令 实际就是两个操作数相与 但结果并不赋值给目的操作数
JZ Next ;如果ZF为0 则 跳转至 Next
INC BL ;BL值加一
Next:
INC SI ;地址+1
LOOP Judge
MOV RESULT,BL;将BL的值赋值给RESULT
;================================================================
MOV AH,4CH
INT 21H
Code ENDS
END Start
思路三(最先想到的复杂思路 使用DIV 做 除法)
Data SEGMENT
Abits DB 51,30,43,107,89,90,200,27,70,66
RESULT DB ?
Data ENDS
Code SEGMENT
ASSUME CS:Code,DS:Data
Start:
MOV AX,Data
MOV DS,AX
;================================================================
MOV BX,OFFSET Abits ;求 Abits 在DS中的有效地址
MOV RESULT,0 ;将 RESULT 赋值为0
MOV DL,2 ;将除数设置为2
MOV CX,10 ;循环次数为10
Judge:
MOV AL,[BX] ;将Abits中的值依次赋值给AL
;这里不使用CBW是因为 如果D7位1 则AH 就变为了0FFH,除法就会出错
MOV AH,0 ;将AH赋值为0
ADD BX,1 ;使地址+1
DIV DL ;因为被除数是字节 所以 被除数在AX中 得到的商在AL中 余数在AH中
CMP AH,0 ;比较AH与0
JZ Next ;如果能除尽则AH为0,ZF为1,则继续下一个数
INC RESULT ;奇数加一
Next:
LOOP Judge
;================================================================
Exit:
MOV DH,0 ;将DH清0 只为数据更好看
MOV DL,RESULT ;将结果赋值给DL 这样可以在DEBUG中方便的看到结果
MOV AH,4CH
INT 21H
Code ENDS
END Start