我在汇编程序 emu 8086 中遇到问题,当我打印两个数字的子结果时

I have an issue in assembly program emu 8086, when I print the sub result for two number

我编写一个汇编程序,让用户输入 2 个整数,将它们存储在堆栈中,然后显示它们的子项:

这是我的代码:

.MODEL SMALL
.STACK 100H
.DATA 
  msg2 db 0dh,0ah, 'Result:   ',0dh, 0ah, '$' 
.CODE
MAIN PROC  
     mov ax,@data
     mov ds,ax
     mov cx, 2
      mov ah,1
TOP:
      int 21h 
      add al, 48h
      push ax
      LOOP TOP
      mov ah,9
      lea dx,msg2
      int 21h 
     XOR bx, bx
     mov cx,2
     add_:
      pop ax
      sub bx,ax
      LOOP add_
    mov ah, 2
    mov dl,bl
    sub dl,48h
    int 21h

但它打印得像一个字符!我怎样才能用正确的整数打印它?

注意:如果我将这两个数字相加,但是 sub dl,30h 它打印出一个正确的整数,错误是什么?

好吧,您使用的是一个非常古老和过时的汇编程序,呵呵,而且它不是那么灵活。好吧,首先,处理器在谈论字符时只知道整数,所以,如果你想打印一个整数,它将被打印为 char 表示。 Kowing 这种情况,你必须将子结果的每个数字路由到它的正确字符表示,因为你需要一个 ASCII table (另外,如果我没记错的话,emu 有一个内置的在 ASCII 字符的图像中)。

例如,如果您执行“6-3”,则子结果为“3”,因此,要将其路由到正确的 ASCII 字符(根据给定的 table)您必须将它添加 48 或 30h,因此,48+3 = 51 或 30h+3 = 33h,并且该整数是“3”字符的正确 ASCII 整数。如果你有像“23-3=20”这样的东西,那么你必须对每个数字做同样的事情,这意味着,0 + 30h = 30h,和 2+30h = 32h,所以你必须先打印32h 字符,然后是 30h 字符,两者都对应于它们正确且各自的 ASCII 表示形式。

所以,简而言之,根据给定的table(你的emu可能不同),要正确打印结果,你必须在每个数字上加上30h,然后打印它们。

  mov cx, 2
  mov ah,1
TOP:
  int 21h 
  add al, 48h
  push ax
  LOOP TOP

您从 DOS 获得的单个数字输入是 [48,57] 范围内的 ASCII。你把它变成一个数字,你可以通过 减去 48 进一步处理。即十进制48或十六进制30h!

  mov  cx, 2
  mov  ah, 01h
TOP:
  int  21h
  sub  al, 30h     ;From character "0", "1", ... to number 0, 1, ...
  push ax
  loop TOP

XOR bx, bx
 mov cx,2
add_:
 pop ax
 sub bx,ax
 LOOP add_
 mov ah, 2
 mov dl,bl
 sub dl,48h
 int 21h

当涉及到减去两个数字时,这不是您的程序所做的。你目前否定了他们的总和,有点!

此外,这两个数字都保存在一个字节中,即 AX 的最低 8 位,更广为人知的是 AL。减法必须只处理这8位部分。

 pop  dx        ; pop the 2nd inputted number
 pop  ax        ; pop the 1st inputted number
 sub  dl, al    ; calculate (2nd - 1st)
 mov  ah, 02h
 add  dl, 30h
 int  21h

要将减法结果转回可显示字符,请添加十进制数 48 或十六进制数 30h。


要获得正确的结果(程序无法处理负数),请确保您输入的第一个数字小于或等于您输入的第二个数字。例如“4”然后“9”将输出“5”。