我试图建立一个程序在emu8086这将是作为输入1 8位二进制数,然后在输出中显示它的十六进制形式。
我的代码是这样的:
data segment
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
mov ax,data
mov ds,ax
mov cx,0
mov bl,8
input:
mov ah,07h
int 21h
cmp al,46
sub al,30h
cmp al,0
je valid
cmp al,1
je valid
jmp input
valid:
cmp bl,0
je exit
sub bl,1
shl cl,1
add cl,al
jmp input
exit:
mov bl,15
and bl,cl
cmp bl,0
je printzero
cmp bl,1
je printone
cmp bl,2
je printtwo
cmp bl,3
je printthree
cmp bl,4
je printfour
cmp bl,5
je printfive
cmp bl,6
je printsix
cmp bl,7
je printseven
cmp bl,8
je printeight
cmp bl,9
je printnine
cmp bl,10
je printa
cmp bl,11
je printb
cmp bl,12
je printc
cmp bl,13
je printd
cmp bl,14
je printe
cmp bl,15
je printf
printzero:
mov dl,'0'
mov ah,02h
int 21h
jmp exit2
printone:
mov dl,'1'
mov ah,02h
int 21h
jmp exit2
printtwo:
mov dl,'2'
mov ah,02h
int 21h
jmp exit2
printthree:
mov dl,'3'
mov ah,02h
int 21h
jmp exit2
printfour:
mov dl,'4'
mov ah,02h
int 21h
jmp exit2
printfive:
mov dl,'5'
mov ah,02h
int 21h
jmp exit2
printsix:
mov dl,'6'
mov ah,02h
int 21h
jmp exit2
printseven:
mov dl,'7'
mov ah,02h
int 21h
jmp exit2
printeight:
mov dl,'8'
mov ah,02h
int 21h
jmp exit2
printnine:
mov dl,'9'
mov ah,02h
int 21h
jmp exit2
printa:
mov dl,'A'
mov ah,02h
int 21h
jmp exit2
printb:
mov dl,'B'
mov ah,02h
int 21h
jmp exit2
printc:
mov dl,'C'
mov ah,02h
int 21h
jmp exit2
printd:
mov dl,'D'
mov ah,02h
int 21h
jmp exit2
printe:
mov dl,'E'
mov ah,02h
int 21h
jmp exit2
printf:
mov dl,'F'
mov ah,02h
int 21h
jmp exit2
exit2:
mov bl,240
and bl,cl
cmp bl,0
je printzero2
cmp bl,1
je printone2
cmp bl,2
je printtwo2
cmp bl,3
je printthree2
cmp bl,4
je printfour2
cmp bl,5
je printfive2
cmp bl,6
je printsix2
cmp bl,7
je printseven2
cmp bl,8
je printeight2
cmp bl,9
je printnine2
cmp bl,10
je printa2
cmp bl,11
je printb2
cmp bl,12
je printc2
cmp bl,13
je printd2
cmp bl,14
je printe2
cmp bl,15
je printf2
printzero2:
mov dl,'0'
mov ah,02h
int 21h
jmp exit3
printone2:
mov dl,'1'
mov ah,02h
int 21h
jmp exit3
printtwo2:
mov dl,'2'
mov ah,02h
int 21h
jmp exit3
printthree2:
mov dl,'3'
mov ah,02h
int 21h
jmp exit3
printfour2:
mov dl,'4'
mov ah,02h
int 21h
jmp exit3
printfive2:
mov dl,'5'
mov ah,02h
int 21h
jmp exit3
printsix2:
mov dl,'6'
mov ah,02h
int 21h
jmp exit3
printseven2:
mov dl,'7'
mov ah,02h
int 21h
jmp exit3
printeight2:
mov dl,'8'
mov ah,02h
int 21h
jmp exit3
printnine2:
mov dl,'9'
mov ah,02h
int 21h
jmp exit3
printa2:
mov dl,'A'
mov ah,02h
int 21h
jmp exit3
printb2:
mov dl,'B'
mov ah,02h
int 21h
jmp exit3
printc2:
mov dl,'C'
mov ah,02h
int 21h
jmp exit3
printd2:
mov dl,'D'
mov ah,02h
int 21h
jmp exit3
printe2:
mov dl,'E'
mov ah,02h
int 21h
jmp exit3
printf2:
mov dl,'F'
mov ah,02h
int 21h
jmp exit3
exit3:
mov ax, 4c00h
int 21h
ends
end start
字符串
我很快意识到,你不需要把每个输入都存储在一个数组中,你可以把存储数字的寄存器的值左移1,然后加上输入(1或0)。好吧,我希望我的代码能工作,但我遇到了一个问题:
存储我的数字值的寄存器是CL
。如果我按此顺序键入11110000
,则CL
的值将变为F0
,这就是我想要的。我将其通过Fh
的AND掩码提取4 LSB,然后通过F0h
的AND掩码提取4 MSB,但在输出中我得到00
.老实说,我不知道我错在哪里。BL
寄存器的值变得与CL
寄存器的值相同,但它仍然不起作用。
1条答案
按热度按时间qybjjes11#
必要的更正
字符串
cmp al,46
指令没有任何用处。它是以前编辑时留下的:只需删除它。您可以简化检查和循环:
的数据
and
所做的是从BL寄存器中删除低半字节,但高半字节仍然保留在原来的位置。这意味着BL中的值为{0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240}。然后,* 快速修复 * 是替换
cmp bl,?
指令系列:型
改进的第一步
目前你的程序包含很多重复的指令。更好的解决方案存在,我相信@PeterCordes提供的链接会揭示这些。
尽管如此,除了自己完成整个任务之外,我建议你学习下面的代码,你会发现这已经大大简化了程序,并且它演示了如何编写可读的代码。请注意,我并不是把它作为 * 最佳 * 解决方案:
型
最终改进步骤
因为你的程序包含8个从键盘输入的字符和2个输出到屏幕的字符,所以优化的版本应该关注代码大小而不是执行时间,这10个DOS函数所花费的时间几乎占了执行时间的100%!
由于所有的重复指令,你的程序目前包含471字节。我的“第一步”解决方案已经将这个数字降低到255字节,但我们肯定可以做得更好吗?
让我们看看这个程序是怎么做的,你输入八个二进制数字,合并把它们组合成一个字节大小的值,然后立即把这个字节分解成两个半字节。
通常,(相当大的)速度增益或大小减小来自于我们使用的方法的根本改变。我建议的是不必将一个字节分解为两个半字节。下面的片段重复两次,只有四个二进制数字的输入被转换为一个十六进制字符。
型
型
这些优化的片段是使用FASM组装的。