【问题标题】:How to divide two digit number怎么除两位数
【发布时间】:2017-08-19 03:09:23
【问题描述】:

我需要显示问题,用户将回答 Y 或 N。我总共有 5 个问题,1 个问题有 20 分。我需要 5 * 20=100 之类的东西。 当用户回答 Y 时,countY db 0 将增加 20

我已经成功计算了分数,但是如何显示分数是两位数(例如 80),也可能是三位数(例如 100)。

Q1: 
    mov ah, 09h
    lea dx, msgq1
    int 21h
    mov ah, 01h
    int 21h
    mov myInput, al
    cmp myInput, 59h
    JE I1
    jmp Q2


  I1:
    mov dl, countY
    add dl,20
    mov countY, dl

  ;calculation
  Cal:
    mov ah,02h
    mov dl, countY
    add dl, 30h  ; display countY=80;
    mov countY, dl
    int 21h

    ;NOT WORKING, ERROR CODE
    mov bl,10
    mov al, countY
    cbw
    div bl

    mov q, al
    mov r, ah

    mov ah, 02h
    mov q, al
    int 21h

【问题讨论】:

  • 不加1,不如add dl,20
  • 但是我还能使用countY db 0 吗?因为是两位数?
  • 使用db 表示这是Data,即1 Btye 长。一个字节可以保存从 0 到 255 的值,因此 countY 可以保存“100”。但是,数字 0 和字符串 '0' 之间存在差异。数字用于计算,字符串用于显示。 IOW,要显示一个数字,你必须把它变成一个字符串。这就是您的add dl, 30h 代码所做的(30h == '0'、31h = '1' 等)。但是这个技巧不适用于超过 9 的数字(30h + 10 = ':')。您需要使用不同的方法来显示大于 9 的数字。
  • cbw 将 AL 符号扩展为 AX,但您使用的是 unsigned div 而不是已签名的 idiv。只要您知道您的输入已知小于 128,这并不重要,我猜。
  • 你得到什么错误代码?详细描述“不工作”的含义。

标签: assembly x86


【解决方案1】:
cal:
mov ah,02h
mov dl, countY
add dl, 30h  ; display countY=80;
mov countY, dl
int 21h
;NOT WORKING, ERROR CODE
mov bl,10
mov al, countY
cbw
div bl

有了这个除法,你就走在了正确的道路上,但它上面的几行确实破坏了 countY 中的值,这太糟糕了。


从除法中得到商和余数后,您需要在 DOS 中显示它们。首先是商,然后是余数。但千万不要忘记将它们变成字符,每一个都加上 30h。

cal:
  mov bl,10
  mov al, countY     ;Values are {0,20,40,60,80}
  cbw                ;Prepare for division of AX/BL
  div bl             ; -> AL=quotient AH=remainder
  mov  dx, ax        ;Conveniently moving both to DX
  add  dx, 3030h     ;Adding 30h to each in a single instruction
  mov  ah, 02h
  int  21h           ;Display the tenths
  mov  dl, dh
  mov  ah, 02h
  int  21h           ;Display the ones

唯一缺少的是分数可能精确为 100 的情况,因此需要 3 位数字。
只需检测它,显示前导“1”,从商中减去 10,然后像以前一样继续:

cal:
  mov  bl,10
  mov  al, countY    ;Values are {0,20,40,60,80,100}
  mov  ah, 0         ;Prepare for division of AX/BL
  div  bl            ; -> AL=quotient AH=remainder
  cmp  al, 10
  jl   Skip
  push ax            ;Save AX because the DOS call destroys it's value
  mov  dl, "1"
  mov  ah, 02h
  int  21h           ;Display the hundreds
  pop  ax            ;Restore AX
  sub  al, 10
Skip:
  mov  dx, ax        ;Conveniently moving both to DX
  add  dx, 3030h     ;Adding 30h to each in a single instruction
  mov  ah, 02h
  int  21h           ;Display the tenths
  mov  dl, dh
  mov  ah, 02h
  int  21h           ;Display the ones

通过将cbw改成mov ah,0,这个版本的代码可以显示从0到199的所有数字。

【讨论】:

    猜你喜欢
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多