x86 Преобразование символа ASCII в цифру - PullRequest
0 голосов
/ 25 февраля 2012

У меня было немного времени с домашним заданием, и я хотел бы получить какое-то руководство.Назначение требует, чтобы вы преобразовали символьную строку ASCII в любой базе и вывели в любую базу.Программа зависает, когда я вызываю процедуру AsciiToDigit (вложенную в процедуру ReadInteger), и я не могу понять, почему.Отладчик не помогает, потому что он ничего не делает, но зависает, когда попадает в эту часть программы.

Я вполне уверен, что мне нужно сначала преобразовать символ в цифру, чтобы сделать это правильно, но, возможно, я что-то упустил.Спасибо за любую помощь, которую может предоставить любой.

    TITLE MASM Template                     (main.asm)

; Description:
; 
; Revision date:

INCLUDE Irvine32.inc
.data
basePrompt BYTE "What base (2-16 or 0 to quit): ",0
numPrompt BYTE "Number please: ",0
invalid BYTE "Invalid base, please try again.",0
base2 BYTE "Base 2: ",0
base8 BYTE "Base 8: ",0
base10 BYTE "Base 10: ",0
base16 BYTE "Base 16: ",0
base DWORD 0


.code
main PROC
        call Clrscr
    State0:                             ; initial state to accept base number
        mov edx, OFFSET basePrompt
        call ReadBase
        cmp al, '0'                     ; check if 0 entered    
        je ProgEnd                      ; jump to ProgEnd if 0 entered
        mov base, ebx
        mov edx, OFFSET numPrompt
        call WriteString
        call ReadInteger

        mov ebx, 2
        mov edx, OFFSET base2
        call WriteString
        call WriteInteger
        mov ebx, 8
        mov edx, OFFSET base8
        call WriteString
        call WriteInteger
        mov ebx, 10
        mov edx, OFFSET base10
        call WriteString        
        call WriteInteger
        mov ebx, 16
        mov edx, OFFSET base16
        call WriteString
        call WriteInteger


        call Crlf
        jmp State0                      ; jump back to beginning of program

    ProgEnd:                            ; jump point to end of programt

    exit
main ENDP

;-----------------------------------------------------
ReadInteger PROC
;
; ReadInteger is passed one argument in bl representing the base of the number to be input. 
; Receives: bl register
; Returns:  EAX
;-----------------------------------------------------
nextChar:
     call ReadChar          ; Get the next keypress
     call WriteChar         ; repeat keypress
     call AsciiToDigit      
     shl   ebx,1            ; shift to make room for new bit
     or    ebx,eax          ; set the bit to eax
     cmp al, 13             ; check for enter key
     jne   nextChar
     ret
ReadInteger ENDP

;-----------------------------------------------------
WriteInteger PROC
;
; Will display a value in a specified base
; Receives: EAX register (integer), bl (base)
; Returns:  nothing
;-----------------------------------------------------

     mov   ecx, 0         ;count the digits
nextDigit:
     mov   edx, 0         ;prepare unsigned for divide
     div   ebx
     push  edx            ;remainder will be in dl
     inc   ecx            ;count it!
     cmp   eax,0          ;done when eax becomes 0
     jne   nextDigit

;now the digits are on the stack
;pop them off and convert to ASCII for output
outDigit: 
     pop   eax              ;digits come off left to right
     add    eax, '30'       ;add 0011 to front to get ASCII
     call  WriteChar
     loop  outDigit

     call Crlf
     ret



    ret
WriteInteger ENDP

;-----------------------------------------------------
ReadBase PROC
;
; Prompts the user for input and stores input into EAX.
; Receives: EDX register
; Returns:  EAX
;-----------------------------------------------------
    Call WriteString

    xor ebx, ebx                ; clear ebx
        call ReadChar
        call WriteChar
        cmp al, '0'
        je Done
        cmp al, 13              ; look for return carriage, jump to end
        je Done
        mov ebx, eax
        shl ebx, 1              ; shift ebx left one
        call ReadChar
        call WriteChar
        or ebx, eax

    Done:
        call Crlf
    ret
ReadBase ENDP

;-----------------------------------------------------
AsciiToDigit PROC
;
; This procedure receives the ASCII code of a digit and returns the numerical digit value.
; Receives: EAX register
; Returns:  EAX
;-----------------------------------------------------
    cmp eax, 61h
    jb Upper
    sub eax,61h
    jmp done

    Upper:
        cmp eax, 41h
        jb Digit
        sub eax, 41h
        jmp done

    Digit:
        sub eax,30h

    done:
        ret
AsciiToDigit ENDP

;-----------------------------------------------------
DigitToAscii PROC
;
; This procedure receives digit and returns Ascii value
; Receives: EAX register
; Returns:  EAX
;-----------------------------------------------------
    add eax, 30h

    ret
DigitToAscii ENDP
END main

1 Ответ

0 голосов
/ 07 октября 2013

Есть несколько вещей, которые я могу видеть до сих пор.

В первой части, когда вы пытаетесь получить базовый номер, если вы вводите 10, код завершается.Я думаю, что вам нужно смотреть на каждый символ, как он введен от пользователя.

Далее вы зависаете, потому что программа, кажется, продолжает получать цифры, пока вы читаете целые числа для этой конкретной базы.В этом пункте кода:

;-----------------------------------------------------
; AsciiToDigit PROC
;
; This procedure receives the ASCII code of a digit and returns 
; the numerical digit value.
; Receives: EAX register
; Returns:  EAX
;-----------------------------------------------------
cmp eax, 61h
jb Upper
sub eax,61h
jmp done

Когда вы вычитаете 61h из EAX, если человек нажал «Enter», это значение исчезнет.Значение 13h будет вычтено из 61h, оставив AL в ACh.Все это означает, что вы никогда не увидите 13h для входа, если код непрерывно вычитает 61h.

Я думаю, вы можете добавить еще несколько cmp и по-настоящему задуматься над кодом в этом отношении.Кроме того, будьте осторожны с тем, что вы нажимаете и вставляете в стек.Посмотрите регистры и посмотрите, что они делают, когда вы выполняете эти функции.

Просто взгляните на некоторые вещи и надеюсь, что это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...