【问题标题】:Displaying a string of of characters from an array of ascii hex values assembly language显示来自 ascii 十六进制值数组的字符串汇编语言
【发布时间】:2012-11-07 17:55:18
【问题描述】:

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

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

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

代码应该如何工作
它会提示您输入一个数字(该数字应该可以是任何无符号 16 位整数)
你输入一个数字然后按回车
输入另一个数字按回车
输入另一个数字按回车(这样应该最多可以输入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

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

【问题讨论】:

  • Mov dx, word ptr InputString[di] 在我看来不合适。在那里试试lea
  • 感谢您对打印的帮助。它现在可以正确显示数字,但现在我意识到它的其余部分并没有我想象的那么好。
  • 我的程序集有点生锈了,但你确定它应该是“numberArray dw 10 dup (0)”而不是“numberArray dw 0 dup (10)”吗?

标签: assembly ascii tasm


【解决方案1】:

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

编辑:现在打印工作正常,但我意识到其余部分比我想象的要复杂。例如,如果我输入任何低于 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 - 这正是BinaryValue 为2560 或更大时发生的情况:2560 / 10 = 256,不适合al。所以处理器引发了一个Divide 异常——俗称Division by zero,因为这是最简单的方法,但在其他情况下也会引发。

【讨论】:

    猜你喜欢
    • 2012-01-08
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 2011-04-14
    • 2013-05-29
    • 1970-01-01
    相关资源
    最近更新 更多