我的乘法和加法代码没有产生正确的结果

My code that multiplies and adds does not produce the correct result

我要计算这个周长表达式

(hight * 2) + (width * 2)

示例:

Enter hight: 3
Enter width: 2
perimeter is : 10

Enter hight: 1
Enter width: 1
perimeter is : 4

.model small
    cr equ 0Dh
    lf equ 0Ah
.data
    msg1 db cr,lf,'Enter hight: $'
    msg2 db cr,lf,'Enter width: $'
    msg3 db cr,lf,'perimeter is : $'
.stack 100h
.code
main    proc
    mov ax,@data
    mov ds,ax
    lea dx,msg1
    mov ah,9h
    int 21h
    mov ah,1h
    int 21h
    sub al,30h
    mov cl,2
    mul cl
    mov bx,ax
    mov ax,@data
    mov ds,ax
    lea dx,msg2
    mov ah,9h
    int 21h
    mov ah,1h
    int 21h
    sub al,30h
    mov cl,2
    mul cl
    mov cx,ax
    mov ax,@data
    mov ds,ax
    lea dx,msg3
    mov ah,9h
    int 21h
    add cx,bx
    mov ah,2h
    int 21h
    mov ah,4ch
    int 21h
main    endp
end main

我的代码没有给出正确的结果。我该如何修复我的代码?

add cx,bx
mov ah,2h
int 21h

您已将结果放入 CX 寄存器,但单字符输出函数 02h 需要您在 DL 寄存器中的字符。

快速修复:

mov dl, cl
add dl, '0'
mov ah, 02h
int 21h

由于这会输出单个字符,因此您不应期望它会显示第一个示例 (10) 中的两位数结果!


两次输入9得到的最长周长(36)
接下来的代码可以输出 [0,99]:

范围内的数字
  mov al, cl      ; [0,36]
  aam             ; -> AH = perimeter / 10    AL=perimeter % 10
  add ax, 3030h
  mov cx, ax
  cmp ch, "0"
  je  SkipLeadingZero
  mov dl, ch      ; tens
  mov ah, 02h
  int 21h
SkipLeadingZero:
  mov dl, cl      ; ones
  mov ah, 02h
  int 21h

一些额外的建议

  • 不需要每次输出信息都重新加载DS段寄存器

  • 您可以重新排列表达式以简化计算

      (hight * 2) + (width * 2) <=> (hight + width) * 2
    
  • 乘以 2 应通过向左移位一次来代替。

      (hight + width) * 2 <=> (hight + width) << 1
    

假设 hightBL 中并且 widthCL:

mov al, bl    ; BL=[0,9]
add al, cl    ; CL=[0,9]
shl al, 1     ; -> AL=[0,36]
aam
...