将 AX 寄存器与零 8086 进行比较

问题描述 投票:0回答:1

大家好,我有一个小程序可以将二进制字符串转换为十进制,我将其正确存储在 bx 中,但是当我想在这个循环中打印 bx 时出现问题,它甚至打破了 ax 仍然大于零

LEA di, fdnum
mov cx,0ah
xor ax,ax 
mov ax,bx 
xor dx,dx
ST : ; bx still bigger than 0 

div cx
mov bx ,ax
add dl ,30h
MOV AH, 02h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;tester
INT 21h ; print the length of the binary number
mov [di],dl
inc di
mov ax,bx 
xor dx,dx
CMP AX, 0
JG ST

感谢任何试图帮助我的人

完整代码

.model small
.STACK 300h
.data
    welcome DB 'Welcome, please enter binary number max(10 digits)',0Ah,0Dh,'Press e to end',0Ah,0Dh,'$'
    msg1 DB 0Ah,0Dh,'You entered: ',0Ah,0Dh,'$'
    error DB ' Not an option, sorry. Enter again: ',0Ah,0Dh,'$'
    obtions DB 0Ah,0Dh,0Ah,0Dh,'convert it to ',0Ah,0Dh,'1-decimal',0Ah,0Dh,'2-octal',0Ah,0Dh,'3-hexa',0Ah,0Dh, '9-End',0Ah,0Dh,'$'
    bnum DB 11 DUP(?) ; buffer to store the binary number
    rbnum DB 11 DUP(?) ; buffer to store the reversed binary number
    fdnum DB 11 DUP(?) ; buffer to store the final decimal answer number
    length_msg db 0Ah,0Dh,'Length is: ','$'
    lenght_bnum db 0 ; lenght of the binary number
    fans db 0 ; final answer
    hex_num db 5 DUP ('$') ; buffer to store the hexadecimal number
    endl DB 0Ah,0Dh
    
    dec_result db 6 dup (?) ; decimal result will be stored here 
    oct_result db 5 dup (?) ; octal result will be stored here 
    dec_result_len db 0
.code
MAIN PROC  
    .startup

    ; print welcome
    MOV ah ,09h
    LEA dx , welcome
    int 21h
    xor ax, ax ; clear ax register

    
    ; Read string
    LEA SI, bnum ; load the address of the buffer into SI
    MOV CX, 10 ; set the counter to 10
    mov bx, 0 ; counter for the lenght of the binary number
READ:
    MOV AH, 01h 
    INT 21H ; read a character
    MOV [SI], AL ; store the character in the buffer
    CMP AL, 0Dh ; if equal to carriage return "Enter", jump string_end
    JE string_end ; if equal, jump string_end
    INC SI ; increment the pointer
    XOR AX, AX
    inc bx 
    LOOP READ ; repeat until CX = 0
string_end:
    MOV BYTE PTR [SI], '$' ; add the string terminator
    ;;;reverse bnum
    dec si
    LEA di, rbnum ; load the address of the buffer into SI
    MOV CX, bx ; set the counter to 10
reverse:
    mov al ,[si] 
    mov [di] ,al
    inc di
    dec si
    loop reverse
    
    ; add the string terminator
    inc di
    MOV BYTE PTR [SI], '$' ;
    ;;;
    LEA DX, msg1 
    MOV AH, 09h 
    INT 21h ; print msg1 "You entered:"

    LEA DX, bnum 
    MOV AH, 09h 
    INT 21h ; print the binary number

    xor si, si
    lea dx, length_msg
    mov ah, 09h
    int 21h ; print "Length is:"

    mov lenght_bnum, bl ; store the lenght of the binary number in lenght_bnum
    mov dl, lenght_bnum
    add dl, 30h
    MOV AH, 02h
    INT 21h ; print the lenght of the binary number


    ; print obtions
obtion:
    mov ah, 09h
    LEA dx, obtions
    int 21h

    ; read obtion and store it in al
    mov ah, 01h ; 
    int 21h ; 
    
    
    ;switch
    cmp al,'1'
    je decimal
    cmp al,'2'
    je octal
    cmp al,'3'
    je hexadecimal
    cmp al,'9'
    je endd
    
    ; print error if not 1 or 2 or 3 or 9, and jump to obtion
    mov ah ,09h 
    LEA dx , error
    int 21h
    jmp obtion
    
decimal:
    mov cx ,bx 
    xor bx ,bx ;reset to zero to store answer
    mov dx ,1  ;
    LEA di, rbnum
cbd: ; covert binary to decimal loop
    cmp [di],'0'
    je novalue ;if current digit equal 0 skip
    add bx ,dx
novalue:
    inc di
    shl dx, 1 ;multi dx by 2 
    loop cbd
    
    ;;;;;;;;;;;;;;;;strore decimal in string 
    LEA di, fdnum
    mov cx,0ah
    xor ax,ax 
    mov ax,bx 
    xor dx,dx
    ST : ; bx still bigger than 0 
    
    div cx
    mov bx ,ax
    add dl ,30h
    MOV AH, 02h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;tester
    INT 21h ; print the lenght of the binary number
    mov [di],dl
    inc di
    mov ax,bx 
    xor dx,dx
    CMP AX, 0
    JG ST
     dec di
     ;;;;;;;;;;;;;;;;;;;;
         mov ah ,2
         LEA si, fdnum
 printt :
     
     mov al , [di]
     int 21
     dec di
     cmp di,si
     jne printt
     mov bl , [di]
     int 21
    jmp endd
    
   
    
octal:
    jmp endd

hexadecimal:

    jmp endd
    
endd:
    .EXIT 
MAIN ENDP
END MAIN
assembly emu8086
1个回答
0
投票

如果用户决定输入允许的最大二进制位数(您设置为 10),则长度显示将失败!之所以会发生这种情况,是因为读取

add dl, 30h
的简单转换将生成位于 ["0","9"] 范围之外的字符 :。也许将限制设置为 9 个二进制数字?

将 AX 寄存器与零 8086 进行比较

虽然很复杂,但从二进制数到其反向十进制表示的转换例程是正确的。你之所以认为这里有问题,是因为你实际上没有显示结果,那是因为你没有在DL寄存器中传递DOS期望的字符!而且,你通过

int 21h
调用DOS(所以不是通过
int 21
),十六进制后缀在这里非常重要!

printt :
  mov al , [di]   <<<<<<<<<<<<<<  Needs to be DL
  int 21
  dec di
  cmp di,si
  jne printt
  mov bl , [di]   <<<<<<<<<<<<<<  Needs to be DL
  int 21

我不认为将 $ 字符串终止符添加到 rbnum 处的输入的逆值中有何意义。以后你不会再用了,反正目前你在bnum缓冲区前面错误地写了一个“$”!
如果您确实想显示反向输入,请更改:

; add the string terminator
inc di
MOV BYTE PTR [SI], '$' ;

进入

; add the string terminator
MOV BYTE PTR [DI], '$' ;

接下来的代码显示您不需要反转字符串来计算二进制值。您可以直接从 bnum:

处的原始输入得到它
decimal:
  xor  ax, ax     ; reset to zero to store answer
  dec  bx         ; BX is [0,9]
  js   wasEmpty
  mov  dx, 1      ; Weight of the current bit
cbd:              ; Convert binary to decimal loop
  cmp  BYTE PTR [bnum + bx], '0'
  je   novalue    ; if current digit equal 0 skip
  add  ax ,dx
novalue:
  shl  dx, 1      ; Multiply DX by 2 
  dec  bx
  jns  cbd
wasEmpty:
© www.soinside.com 2019 - 2024. All rights reserved.