assembly 一个汇编程序,读取4个整数,找出最小的,并计算总和

vdgimpew  于 4个月前  发布在  其他
关注(0)|答案(1)|浏览(59)

它可以很好地读取整数,也可以很好地找到最小的整数。但是,当和大于9时,它会给出错误的结果。
我试着把BH中的和作为小数来计算。但是,如果我要求它把9和9相加,它会把BH中的12而不是18。

data segment
    msg db "chiffre: $" 
    petit db "plus petit chiffre: $"
    somme db "somme: $"
    
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax
    
    mov ah, 09h
    mov dl, offset msg
    int 21h
    
    mov ah, 01h
    int 21h  
    
    mov bl, al  ; bl contains the smallest number  
    mov bh,al  
    sub bh,'0'
    
    mov cx,3
    etq:  
        mov ah, 02h
        mov dl,0Dh
        int 21h 
        
        mov ah, 02h   
        mov dl,0Ah
        int 21h 
   
        mov ah, 09h
        mov dl, offset msg
        int 21h
        
        mov ah, 01h
        int 21h
        
        cmp al, bl 
        jb min
        jae reste  ; jump to the end of the loop 
        
        min:
            mov bl, al 
    
    reste:
    sub al,'0'         
    add bh,al    
    loop etq

字符串

pcrecxhr

pcrecxhr1#

调试器显示了正确的结果,但使用了十六进制小数。
Displaying numbers with DOS解释了如何将数字转换为十进制字符串,然后显示在屏幕上,这样就不必解释调试窗口中的十六进制值。

mov dl, offset msg

字符串
这是一个你应该注意的错误。DOS.PrintString函数09 h需要的是字长DX寄存器中字符串的地址。你不应该只加载低字节DL,而相信高字节DH包含0。所以写mov dx, OFFSET msg

cmp al, bl 
   jb min
   jae reste  ; jump to the end of the loop 

min:
   mov bl, al 

reste:


你可以很容易地避免跳过新的最小值的赋值。如果你只选择相反的条件跳转,你可以用单个指令jnb reste替换jb minjae reste
我看到你的程序正在重复一些指令。我下面的代码片段,我有循环做4次迭代后,适当的初始化BX循环开始前:

mov  bx, 000Ah  ; BH is sum (0), BL is smallest number (10)  
  mov  cx, 4
etiquette: 
  mov  ah, 09h
  mov  dx, OFFSET msg
  int  21h
  mov  ah, 01h
  int  21h       ; -> AL = ['0','9']
  sub  al, '0'   ; From ['0','9'] to [0,9]
  cmp  al, bl    ; (*)
  jnb  passer
  mov  bl, al    ; Assign a new minimum
passer:
  add  bh, al    ; Sum
  mov  ah, 02h
  mov  dl, 13
  int  21h 
  mov  dl, 10
  int  21h
  loop etiquette


(*)因为最小的数字变量BL被初始化为10,这比用户可以输入的任何(十进制)数字都要大,所以第一个cmp al, bl已经设置了下面的条件,因此第一个新的最小值将从第一个用户输入中分配(就像在程序中一样)。
你的程序可以预期的最大和是36(9+9+9+9)。作为一种替代方法,而不是使用我在上面提供的Q/A中描述的方法,你可以使用下一个代码来显示范围[0,99]中的一个小数字:

mov  al, bh    ; Sum eg. 18
  aam            ; -> AH = AL / 10   AL = AL % 10   eg. AH = 1   AL = 8
  add  ax, '00'  ; Convert into text                eg. AH = '1' AL = '8'
  mov  cx, ax
  mov  ah, 02h
  mov  dl, ch    ; Tens eg. '1'
  int  21h 
  mov  dl, cl    ; Ones eg. '8'
  int  21h

相关问题