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

9rnv2umw  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(76)

我有一个将二进制字符串转换为十进制的小程序。我将其正确地存储在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

klsxnrf1

klsxnrf11#

如果用户决定输入允许的最大二进制位数(您已将其设置为10),则长度显示将失败!这是因为读取add dl, 30h的简单转换将产生位于[“0”,“9”]范围之外的字符**:。是否可以将限制设置为9个二进制位?
比较AX寄存器与零8086
虽然很复杂,但你的从二进制数到它的逆十进制表示的转换例程是正确的。你认为这里有问题的原因是你实际上没有显示结果,这是因为你没有在DOS期望的
DL**寄存器中传递字符!而且,你必须通过int 21h调用DOS(所以不能通过int 21),十六进制后缀在这里非常重要!

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

字符串
我不认为在 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:

相关问题