我想从用户那里得到一个数字(即5),然后从1到<输入(即1 2 3 4)开始打印,但是我的代码并没有以“ 4”停止,而是循环运行到“ d”
我知道循环运行CX次,并且在8086中MOVZX不起作用,这就是为什么我最初将AL移至CL然后将CH清零的原因。
正如有人提到的那样,问题出在我将AL移到CX时,我没有移动值4,而是移动了34(ASCII值4),所以我的循环运行了34次。
现在如何将用户输入值转换为十进制并将其移动到CX。有什么办法可以将用户输入作为十进制值存储在AL中?
org 100h
MOV AH, 1 ; Get user input
INT 21H
DEC AL ; Dec AL to satisfy the condition that it will print till < input
MOV BL,31H ; Initialize BL so that the output starts printing from 1
MOV CL,Al ; set counter register CX
MOV CH,00
Print:
MOV AH, 2 ; for output printing
MOV DL,0DH ; for output printing
INT 21H ; for output printing
MOV DL,0AH ; for output printing
INT 21H ; for output printing
MOV AH,2
MOV DL,BL ; print what is in BL
INT 21H
INC BL ; then increment BL
LOOP Print ; supposed to run the loop on Print what is the value in CL times
hlt
现在如何将用户输入值转换为十进制并将其移动到CX。
}while(--cx)
使用以外的指令,您陷入了忘记除可能之外的循环条件的陷阱loop
。
loop
只是一个窥孔优化dec cx / jnz
(不影响FLAGS)。仅在实际上是最有效的循环方式时才使用它。(或者根本不使用它,因为无论如何您都需要理解条件分支,因此省略loop
/了解/记住的指令要少一些。而且,在大多数现代x86 CPU上,loop
它要比dec / jnz慢得多。如果进行调优,则很好真正的8086,或者针对速度上的代码大小进行优化,但这仅是优化的必要条件。
编写此循环的最简单,最合乎逻辑的方法是:
MOV AH, 1 ; read a char from stdin into AL
INT 21H
mov cl, al ; ending character
mov bl, '1' ; b = current character, starting with '1'
.top: ; do {
... print CR/LF (not shown)
mov dl, bl
int 21h ; With AH=2 from printing CR/LF
inc bl ; b++
cmp bl, cl
jbe .top ; }while(b <= end_char);
请注意,打印后我增加了。如果您在打印前增加,你会使用jb
的}while(b < end_char)
。
在loop
高效的实际8086上,它的确在循环内包含了更多的指令和更多的代码字节,因此可能会更慢(如果我们考虑循环开销很重要的情况,而不是int 21h
在循环内进行3次慢速系统调用)。
但这与较小的总代码大小(从琐碎的循环设置)进行权衡。因此,这是静态代码大小与动态指令计数(以及需要提取的代码字节数,这是8086上的真正问题)之间的折衷方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句