从 1 打印到 < emu8086 中的用户输入

Print from 1 to < user input in emu8086

我想从用户那里得到一个数字(即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
MOV AH, 1  ; Get user input 
INT 21H

如果您输入 5 那么 AL 寄存器将保存数字 35h,这是该键的 ASCII 代码。您显然想要那个键代表的是 5。您需要减去 30h (48)。

mov     ah, 01h  ; DOS.GetKey 
int     21h
sub     al, '0'
dec     al
mov     cl, al
mov     ch, 0

程序的其余部分可以从 1 开始打印到 < 输入。

Now how do I convert my user input value to decimal and move that to CX.

你已经陷入了忘记 }while(--cx) 以外的循环条件是可能的陷阱,使用 loop.[=23 以外的指令=]

loop 只是 dec cx / jnz 的窥孔优化(不影响 FLAGS)。仅当这实际上是最有效的循环方式时才使用它。 (或者根本就不要使用它,因为无论如何您都需要了解条件分支,所以省略 loop 可以减少学习/记住的指令。另外,on most modern x86 CPUs, loop is much slower than 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).


在真正的 8086 上,loop 是高效的,这在循环内确实有更多的指令和更多的代码字节,因此可能会更慢(如果我们考虑循环开销很重要的情况,而不是循环内的 3 倍慢 int 21h 系统调用)。

但这与较小的总代码大小(来自简单的循环设置)进行了权衡。因此,这是静态代码大小与动态指令数(以及需要获取的代码字节数,这是 8086 上的真正问题)之间的权衡。