汇编语言循环不工作

Assembly Language Loop Not working

我是汇编初学者language.I 想用空格打印 1-9。我想这样打印

1 2 3 4 5 6 7 8 9

这是我正在使用的代码 masm 此代码挂起 命令提示符

为什么这不起作用?

DATA_SEG SEGMENT
DATA_SEG ENDS
CODE_SEG SEGMENT 
        ASSUME CS:CODE_SEG , DS:DATA_SEG
MAIN PROC FAR
    MOV AH,02
    MOV AX,'0'
    MOV CX,10
L1:
    MOV DX,AX
    INT 21H
    INC AX
    LOOP L1

    MOV AX,4C00H 
    INT 21H
    MAIN ENDP
CODE_SEG ENDS
END MAIN    
MOV AH,02
MOV AX,'0'   ; sets ah=0.  this is your bug (there may be others).

以下循环打印所有数字,但不留下 spaces。我会把它留给你。 (编辑:糟糕,这会打印 0..9 的数字,因为这就是您的代码在系统调用后对 inc 执行的操作,并且从“0”开始。显然以 '1' 开头。)

    MOV   AH, 2
    mov   dl, '0'
.l1:
    INT   21H
    INC   dl
    cmp   dl, '9'
    jle .l1

假设int 21 / ah=2 打印dl中的字符。 int 21 不会破坏任何寄存器 (except the return value in al),因此您不需要在循环内 mov dx, ax。 (编辑:是的,你这样做,因为如果你一次打印一个字节,你需要交替 spaces 和数字)。

使用 AH=09h 编写整个字符串意味着您可以高效地构造它,然后打印整个字符串。例如

    ;; Not debugged or tested (I don't keep DOS around...)
    ;; So I may have gotten some 2-character constants in the wrong order
    sub    sp, 22      ; reserve space (slightly more than necessary because I didn't debug or even test this)
    mov    di, sp
    mov    ax, '0 '
.l1:
    stosw               ; store digit and trailing space into [edi+=2]
    inc    al
    cmp    al, '9'
    jle   .l1

          ; note that NASM doesn't process \ escapes, but MASM does
    mov    word [di], '\n$'   ; newline and DOS end-of-string marker
    mov    dx, sp             ; dx=input param = start of our buffer
    ; this only works if DS=SS, I guess.  Yay segments.
    mov    ah, 09h            ; DOS write string syscall
    int    21h
    ...
    add    sp, 22             ; release the stack buffer

    ...

请注意,与大多数 asm 示例不同,此代码不使用静态缓冲区(bss 或数据部分)。这可能是因为细分。不要花太多时间学习段,它们对现代操作系统下的现代程序没有用。请参阅 wiki。

另请注意,它不使用 loop,因为 that's slow.

我本可以使用 push 在堆栈上创建字符串,但这可能更令人困惑,而且您永远不会看到编译器这样做。通过推送,它会像

    push   '\n$'
    mov    ax, '9 '
.l1:
    push   ax       ; like stosw in reverse, but with SP instead of DI
    dec    al
    cmp    al, '0'
    jge    .l1

    ... make the system call with dx=sp

不过,这会在 9 之后留下尾随 space。

哇我用简单的方式打印它logic.But我认为这不是一个有效的解决方案。

DATA_SEG SEGMENT
ONE DW 48
SPACE DW 32
DATA_SEG ENDS
CODE_SEG SEGMENT 
        ASSUME CS:CODE_SEG , DS:DATA_SEG
MAIN PROC FAR

    MOV AX,DATA_SEG ; TO INTIALIZE DATA SEGMETN
    MOV DS,AX


    MOV AH,02

    MOV CX,10
      L1:

    MOV DX,ONE
    INT 21H
    MOV DX,SPACE
    INT 21H
    INC ONE
             LOOP L1

    MOV AX,4C00H 
    INT 21H
    MAIN ENDP
CODE_SEG ENDS
END MAIN