在装配屏幕上打印内存值

printing a memory value on the screen in assembly

我写了一个汇编代码来对五个数字求和。然后将最终值存储在内存中。

dtseg    segment
data     dw       27345,28521,29533,30105,32375
sum      dw       ?  
MSG1     DB "The sum is : $"  
dtseg    ends
;---------------------
cdseg    segment
main     proc     far
     assume   cs:cdseg,ds:dtseg,ss:stseg
     mov      ax,dtseg
     mov      ds,ax
     clc                       ; clear the carry
     mov      si,offset data   ; first location of data
     mov      cx,04            ; setting the counter
     mov      ax,0             ; clear ax
     mov      bx,ax            ; clear bx
back:add      ax,[si]          ; the first round: 0+27345
     adc      bx,0             ; if there is a carry, add that to bx
     inc      si               ; two inc because traversing words
     inc      si
     dec      cx               ; count down
     jnz      back             ; do that for other numbers
     mov      sum,ax           ; the final value
     mov      sum+2,bx         ; the carries are stored in bx

     lea      dx,MSG1          ; trying to display the result
     mov      ah,09h
     int      21h  
     mov      ah, 4cH          ; return to DOS
     int      21h
main     endp
cdseg    ends  
         end      main

我遵循了基于此 topic 的示例,但是它在 emu8086

中不起作用

This example 向您展示如何将 AX 中的 WORD 值转换为字符串并输出。您想要将 DWORD 值转换为字符串。在您的情况下,您可以利用 DIV div 在寄存器 DX:AX 中放置一个 DWORD 的优势。在示例中 DX 设置为 0,因此第一个想法是删除行 xor dx, dx。但是你第一次需要DX,那么你必须清除它,因为它保存着DIV之后的余数。诀窍是在 之后 而不是在 div 之前执行清除。所以会第一次使用,每次重复都会清零。

dtseg    segment
data     dw 27345,28521,29533,30105,32375   ; Sum: 147879

sum      dw  ?, ?               ; two WORD = one DWORD
MSG1     DB "The sum is : $"
DECIMAL  db "0000000000$"       ; space for the result
dtseg    ends
;---------------------
cdseg    segment
main     proc     far
     assume   cs:cdseg,ds:dtseg,ss:stseg
     mov      ax,dtseg
     mov      ds,ax
     clc                       ; clear the carry

     mov      si,offset data   ; first location of data
     mov      cx,5             ; setting the counter
     mov      ax,0             ; clear ax
     mov      bx,ax            ; clear bx
back:add      ax,[si]          ; the first round: 0+27345
     adc      bx,0             ; if there is a carry, add that to bx
     inc      si               ; two inc because traversing words
     inc      si
     dec      cx               ; count down
     jnz      back             ; do that for other numbers

     mov      sum,ax           ; the final value
     mov      sum+2,bx         ; the carries are stored in bx

     call mem_to_dec

     lea      dx,MSG1          ; trying to display the result
     mov      ah,09h
     int      21h
     lea      dx,DECIMAL          ; trying to display the result
     mov      ah,09h
     int      21h

     mov      ah, 4cH          ; return to DOS
     int      21h
main     endp

mem_to_dec proc
    mov ax, [sum]
    mov dx, [sum+2]

    mov bx, 10                  ; divisor
    xor cx, cx                  ; CX=0 (number of digits)

    @First_Loop:
        div bx                  ; DX:AX / BX = AX remainder: DX
        push dx                 ; LIFO
        inc cx                  ; increment number of digits
        xor dx, dx              ; Clear DX for the next DIV
        test  ax, ax            ; AX = 0?
        jnz @First_Loop         ; no: once more

        mov di, OFFSET DECIMAL  ; target string DECIMAL
    @Second_Loop:
        pop ax                  ; get back pushed digit
        or ax, 00110000b        ; to ASCII
        mov byte ptr [di], al   ; save AL
        inc di                  ; DI points to next character in string DECIMAL
        loop @Second_Loop       ; until there are no digits left

        mov byte ptr [di], '$'  ; End-of-string delimiter for INT 21 / FN 09h
        ret
mem_to_dec endp

cdseg    ends
         end      main

如果结果不适合 AX 寄存器,DIV 会出现问题。然后你会得到一个溢出错误。