无法让汇编程序正确检查数字

时间:2013-09-17 16:30:17

标签: assembly

我正在尝试编写一个读取数字的汇编语言程序,并将其与5进行比较。如果数字小于5,程序应该成功结束,否则它应显示错误消息并提示再次输入数字。无论我做什么,我似乎都没有成功地结束它,它总是跳到错误标签。

我的代码:

bits 16
org 0x100   ;start at offset 100
jmp main

buffer:   db 4  ; define 4 bytes
      db 0  ; actual number of characters entered

msg:      db "Enter a number between 0 and 5 ", 0ah, 0dh, '$' ; define bytes for message

ermsg:    db "The number must be between 0 and 5", 0ah, 0dh, '$';error message if number is too large

main:
dsp_msg:  mov ah, 09    ; screen display
      mov dx, msg   ; mov starting address of msg into dx 
      int 21h   ; display message

in_buff:      resb 20   ; reserve 20 bytes
      mov ah, 0ah   ; service read character
      mov dx, buffer ;move address of parameter block to dx
      int 21h   ;bios system call
      sub dx, 30h

chk_num:  
      cmp dx, '5'   ;compare entered nnumber to 5
      jge err   ;if entered value is greater or equal to 5 jump to err
      jb fin    ;if entered number is below 5 jump to fin

err:      mov ah, 09    ;
      mov dx, ermsg ;move ermsg to dx
      int 21h   ;display error message
      jmp in_buff     

fin:      int 20h

任何想法我做错了什么?

“更新:

我改变了我的代码以使用01功能
但现在我不断收到错误消息“未指定操作大小”

我的新代码:

bits 16
org 0x100   ;start at offset 100
jmp main

buffer:   db 4  ; define 4 bytes
db 0    ; actual number of characters entered

msg:db“输入0到5之间的数字”,0ah,0dh,'$';定义消息的字节

ermsg:    db "The number must be between 0 and 5", 0ah, 0dh, '$';error message if number is too large

main:
dsp_msg:  mov ah, 09    ; screen display
mov dx, msg ; mov starting address of msg into dx 
int 21h ; display message

in_buff:  resb 20   ; reserve 20 bytes
mov ah, 01  ; service read character
mov dx, buffer;move address of parameter block to dx
int 21h ;dos system call

chk_num:  
cmp [dx], 5 ;compare entered nnumber to 5
jge err ;if entered value is greater or equal to 5 jump to err
jb fin  ;if entered number is below 5 jump to fin

err:      mov ah, 09    ;
mov dx, ermsg   ;move ermsg to dx
int 21h ;display error message
jmp in_buff   

fin:      int 20h  

我正在使用nasm进行编译。有谁知道这意味着什么?
对不起,所有的基本问题。这是我第一次使用汇编语言并发现它非常困难......

3 个答案:

答案 0 :(得分:1)

您的代码包含:

sub dx, 30h

从ASCII字符代码中减去48(ASCII 0)。

但是你的代码也包含这一行:

cmp dx, '5'   ;compare entered nnumber to 5

将字符的ASCII值与减去的值进行比较。

您使用的功能(0x0A)正在捕获缓冲输入,因此数据不会放在DX上,而是放在ES:DX上。只需删除sub dx, 30h并且不要比较寄存器值,但是那里有数据:

mov ah, 0ah   ; service read character
mov dx, buffer ;move address of parameter block to dx
int 21h       ;bios system call

chk_num:  
    cmp byte [es:dx+2], '5'   ;compare entered number to 5

BTW你将重写消息数据,所以你的缓冲区应该是这样的:

buffer:   
    db 4  ;this buffer will be 4 bytes long
    db 0  ;well, we don't know how many characters are going to be entered, so `0` will be the best
    dd 0  ;and now the promised 4 bytes for buffer contents

您可能对可以找到的具体功能参考感兴趣here

答案 1 :(得分:0)

  cmp dx, '5'   ;compare entered nnumber to 5

现在,由于5被引用,这可能只是与ASCII字符5(35H)进行比较,而不是与值5进行比较。

我很想去除那些引号。

答案 2 :(得分:0)

在代码中间声明输入缓冲区可能不是一个好主意。把它放在你跳过的区域,或section .bss

int 21h/0Ah的缓冲区需要特殊格式化。第一个字节是要接受的最大字符数。使它至少为2,并且不超过你在缓冲区中实际获得的空间。第二个字节将包含实际输入的字符数。计数将包括结束输入的CR ......它将在缓冲区中。

输入的实际文字将从[buffer + 2]开始。不幸的是,[dx + 2]不是16位代码中的有效有效地址。使用bxsidi进行寻址。 5'5'之间的区别已经包含在内。

如果你想要的只是一个字符,你可能不需要“缓冲输入”中断。拉尔夫布朗的中断名单是你的朋友!