尝试在2个16位寄存器中存储32位数

时间:2018-03-03 02:42:51

标签: assembly nasm x86-16

这是针对8086的,我正在使用NASM。

我有硬件我一直在努力,我应该接受32位二进制数作为输入,将其存储在寄存器对dx:bx中,并将数字输出到屏幕。

我有一个问题,我已经能够解决很长一段时间了。它不是输出输入的32位,而是输出最后输入的16位,然后输出两次。

有人可以看看这个,并帮助我理解为什么我没有得到整个32位数字?

    CPU 286
    org 100h

section .data
    prompt: db  "Please enter a binary number: $"
    msg: db 0Dh,0Ah, "The number you entered is:    $"

section .text   
start:  
    mov ah,9        ; load print function
    mov dx,prompt   ; load prompt to print
    int 21h         ; prompt for input

    mov bx,0        ; bx holds input value
    mov dx,0        ; clear dx
    mov ah,1        ; input char function
    int 21h         ; read char into al

; loop to accept and store input
input:  
    cmp al,0Dh      ; is char = CR?
    je  outputMsg   ; yes?  finished with input
    shl bx,1        ; bx *= 2, shifts msb of BX into CF
    rcl dx,1        ; rotate CF into lsb of DX
    and al,01h      ; converts ASCII to binary value
    or  bl,al       ; "adds" the input bit
    int 21h         ; read next character
    jmp input       ; loop until done

outputMsg:  
    mov ah,9        ; load print function
    mov dx,msg      ; load output message to print
    int 21h         ; print output message

; loop to load either '0' or '1' to print, depending on carry flag
    mov cx, 32      ; loop counter
output: 
    rol bx,1        ; rotate msb into CF
    jc  one         ; if CF is 1, go to "one" loop
    mov dl,'0'      ; of CF is 0, set up to print '0'
    jmp print       ; jump to "print" loop
one:    
    mov dl,'1'      ; set up to print '1'
print:  
    mov ah,2        ; load print char fcn
    int 21h         ; print char
    loop output     ; go to next character



Exit:
    mov ah,04Ch     ;DOS function: Exit program
    mov al,0        ;Return exit code value
    int 21h         ;Call DOS.  Terminate program

1 个答案:

答案 0 :(得分:1)

outputMsg:  
 mov ah,9        ; load print function
 mov dx,msg      ; load output message to print
 int 21h         ; print output message

outputMsg 标签处,DXDX:BX中保存32位数字的高位字。通过写mov dx, msg,你已经将其摧毁了!你需要保留它。

outputMsg:
 push dx
 mov  ah, 09h
 mov  dx, msg
 int  21h
 pop  dx
rol bx,1        ; rotate msb into CF

DX:BX中32位数字的最高有效位(msb)是DX的第15位。
检索它的代码是:

shl  bx, 1     ;Shift low word left, carry gets its highest bit
rcl  dx, 1     ;Bring that carry in high word, carry gets msb

您现在的解决方案是输出" 0"或者" 1"虽然有用,但更清洁的解决方案不会使用jc / jmp说明。那些导致不整洁的代码需要很多标签!

将进位标志的值(0或1)添加到字符" 0"将给你所要求的" 0"或" 1"。

push dx
mov  dl, '0'
adc  dl, 0      ;The immediate is zero, so only the carry gets added!
mov  ah, 02h
int  21h
pop  dx

因为DOS输出函数使用DL,所以有必要保留和恢复DX中保存的数字的高位字。

当然,如果将32位数存储在DI:SIBP:BX等其他寄存器对中,则该程序的某些问题将不存在。鉴于这是HW,push / pop可以正常工作。

作为最后的说明。

mov ah,04Ch     ;DOS function: Exit program
mov al,0        ;Return exit code value

当加载组合在1个字寄存器(AH)中的2个字节寄存器(ALAX)时,您可以通过组合负载来节省代码大小和执行速度:

mov  ax, 4C00h     ;DOS function: Exit program with exit code 0