3

好的,我正在为基于英特尔的计算机作业组装,为了简单起见,教授让我们在 16 位上工作。分配是获取用户输入的数字并将其从 ASCII 转换为整数,然后将该整数存储在数组中。我的这部分工作正常。然后我们从数组中取出整数并将它们转换回 ASCII 并打印到屏幕上。在我打印之前,这在大多数情况下也可以正常工作。

我使用 tasm,当我使用调试器跟踪我的代码时,它会显示它应该显示的数字,但它们被很多空白空间和一些奇怪的字符包围。然后,当我尝试在命令提示符下运行代码时,我得到的只是一些非常混乱的字符,然后它似乎崩溃了。

编辑:现在打印工作正常,但我意识到其余的比我想象的更糟糕。例如,如果我输入任何低于 2559 的数字,它似乎工作得很好,但如果我输入任何数字 2560 或以上,我会得到除以零的错误。对此的任何帮助将不胜感激。

代码应该如何工作
它会提示您输入一个数字(该数字应该可以是任何无符号的 16 位整数)
您输入一个数字并按 Enter 输入
另一个数字按 Enter
输入另一个数字按 Enter(应该能够向上输入以这种方式最多输入 10 个数字)
当您输入完数字后,输入减号“-”
,然后它应该向您重复您输入的数字

这是我的代码:

.MODEL small

.STACK 200h
CR EQU 13
LF EQU 10

.DATA
;variables used by InputNumber procedure
BinaryValue dw 0
CharacterCount dw 0
Index dw 0
Multiplier dw 1
InputString db 7 dup (0)
prompt2 db 'Enter A Number:', '$'


;variables used by LoadArray prcedure
prompt1 db 'You may enter up to 10 positive integers then enter a -1', CR, LF,  '$'
userFlag db 0
numberArray dw 10 dup (0)
numArraySize dw 0

;variables for PrintArray
prompt3 db 'Array data is:', '$'
numSize dw 0

.CODE
Main proc
    MOV ax, @data
    MOV ds, ax
    CALL LoadArray
    CALL PrintArray
    MOV ax, 4c00h
    INT 21h
Main endp





LoadArray proc
    ; informs the user to enter numbers then enter a -1
    MOV ah, 09h
    MOV dx, offset prompt1
    INT 21h

    Mov di, 0
    While1:
        Mov BinaryValue, 0
        Mov CharacterCount, 0
        Mov Index, 0
        Mov Multiplier, 1
        Call InputNumber
        Cmp userFlag, 0
        Jne endWhile1
        Mov bx, BinaryValue
        Mov numberArray[di], bx
        Inc di
        Inc di
        jmp While1
    endWhile1:
    Mov numArraySize, di
    RET
LoadArray endp





InputNumber proc
    MOV ah, 09h
    MOV dx, offset prompt2
    INT 21h

    ;Get character from keyboard
    Mov ah, 01h
    Int 21h

    ;while that character is not the enter key keep getting keys from the keyboard
    Mov si, CharacterCount
    while2:
        Cmp al, 0Dh
        Je endWhile2
        Cmp al, 2Dh
        Je endOfProc
        Mov InputString[si], al
        Inc si
        Mov ah, 01h
        Int 21h
        jmp while2
    endWhile2:
    Mov CharacterCount, si

    ;initializing multiplier and index to the values needed
    Mov Multiplier, 1
    Dec si
    Mov Index, si

    ;loop through InputString array pulling out each character, convert it by removing its ascii bits and muliplying it by its place value  
    Mov cx, CharacterCount
    Mov CharacterCount, 0
    convertLoop:
        Mov al, InputString[si]
        And ax, 0Fh
        Mul Multiplier
        Add BinaryValue, ax
        Mov ax, 10
        Mul Multiplier
        Mov Multiplier, ax
        Dec si
        Loop convertLoop
    RET
endOfProc:
    Mov userFlag, 1
    RET
InputNumber endp




PrintArray proc
    MOV ah, 09h
    MOV dx, offset prompt3
    INT 21h

    Mov si, 0
    doWhile1:
        Mov bx, numberArray[si]
        Mov BinaryValue, bx
        call DisplayNumber
        Inc si
        Inc si
        Cmp si, numArraySize
        jb doWhile1
    RET
PrintArray endp




DisplayNumber proc
    Mov ax, BinaryValue
    ;determine size of the number in BinaryValue
    loop1:
        Mov bl, 10
        Div bl
        cmp al, 0 
        je end1
        Inc numSize
        Mov ah, 0
        jmp loop1
    end1:
    Inc numSize
    Mov di, numSize
    Mov InputString[di], '$'
    dec di
    Mov ax, 0
    Mov ax, BinaryValue
    while3:
        cmp ax, 10
        jb endWhile3
        Div bl
        Or ah, 30h
        Mov InputString[di], ah
        Mov ah, 0
        dec di
        jmp While3
    endWhile3:
    Or al, 30h
    Mov InputString[di], al

    ;print the ascii characters stored in InputString to the screen
    Mov dx, word ptr InputString[di]
    Mov ah, 09h
    Int 21h
    Ret
DisplayNumber endp
end main

我会一直工作到它工作为止,因为我需要它来完成以后的任务。任何帮助将非常感激。即使它是关于如何清理代码或使其更好或更易读(包括样式)的建议。

4

1 回答 1

0

我查看了您的代码,只注意了您问题的这一部分:

编辑:现在打印工作正常,但我意识到其余的比我想象的更糟糕。例如,如果我输入任何低于 2559 的数字,它似乎工作得很好,但如果我输入任何数字 2560 或以上,我会得到除以零的错误。对此的任何帮助将不胜感激。

问题出在DisplayNumber这里:

Mov ax, BinaryValue
;determine size of the number in BinaryValue
loop1:
    Mov bl, 10
    Div bl
    cmp al, 0 
    je end1

Div bl是 8 位除以寄存器,所以源是ax. 它进行除法,并将结果al和余数放入ah- 如下语句cmp al,0测试。

问题是,如果除法的结果不适合al- 这正是BinaryValue2560 或更大时发生的情况:2560 / 10 = 256,不适合al. 所以处理器引发了一个Divide异常——俗称,Division by zero因为这是获得它的最简单方法,但在其他情况下也会引发它。

于 2016-06-14T09:49:01.050 回答