【问题标题】:Trying to store 32-bit number across 2 16-bit registers尝试在 2 个 16 位寄存器中存储 32 位数字
【发布时间】:2018-03-03 02:42:50
【问题描述】:

这是针对 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

【问题讨论】:

  • 因为您在 int 21h 调用中使用它完全丢弃了 dx 中的高位,并且您的循环仅循环 bx 并且根本不关心其中的 dx。您必须实际使用该值来打印它。
  • @SamiKuhmonen 谢谢!多亏了你的建议,我终于让它工作了。

标签: assembly nasm x86-16


【解决方案1】:
outputMsg:  
 mov ah,9        ; load print function
 mov dx,msg      ; load output message to print
 int 21h         ; print output message

outputMsg 标签处,DX 将您的 32 位数字的高位字保存在 DX:BX 中。通过写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 之类的其他寄存器对中,则该程序的某些问题将不存在。鉴于这是硬件,push / pop 有效。


作为最后一点。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-11
    • 2012-01-11
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 2021-03-04
    • 2014-11-18
    • 1970-01-01
    相关资源
    最近更新 更多