汇编语言循环不起作用

时间:2016-03-02 07:17:15

标签: assembly masm

我是汇编语言的初学者。我想用空格打印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    

2 个答案:

答案 0 :(得分:3)

MOV AH,02
MOV AX,'0'   ; sets ah=0.  this is your bug (there may be others).

以下循环打印所有数字,但不留空格。我会把它留给你。 (编辑:oops,这会打印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。 (编辑:是的,因为如果你一次打印一个字节,你需要替换空格和数字。)

使用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之后留下一个尾随空格。

答案 1 :(得分:0)

哇我用简单的逻辑打印它。但我认为这不是一个有效的解决方案。

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