2012-02-25 8 views
0

나는 숙제를하는 데 시간이 많이 걸리므로 약간의 지침을 좋아할 것입니다. 이 할당을 사용하면 모든 기본 및 출력의 ASCII 문자열을 모든 기준으로 변환해야합니다. 이 프로그램은 AsciiToDigit 프로 시저 (ReadInteger 프로 시저 내에 중첩 됨)를 호출 할 때 중단되며 이유를 파악할 수 없습니다. 디버거는 아무 것도하지 않고 프로그램의 해당 부분에 도달하면 정지한다는 점에서 도움이되지 않습니다.x86 ASCII 문자를 숫자로 변환

나는 정확하게 이것을하기 위해 문자를 먼저 숫자로 변환해야하지만 확실하게 뭔가를 놓치고 있다고 확신한다. 누구든지 제공 할 수있는 도움에 감사드립니다.

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 
+2

'add eax, 30h'와'add eax '를 바꾸면 코드 가독성이 향상 될 것입니다. 또한, 아마도'add eax ','30''은'add eax ', 0''이어야합니다. – AusCBloke

+0

대단히 감사합니다. 아직 매달려. –

+0

ReadChar가 EAX에서 결과를 반환합니까? WriteChar는 EAX를 보존합니까? AsciiToDigit은 EAX의 결과를 분명히 예상하므로,이 가정을 확인하십시오. 디버거가 도움이되지 않으면 작동 할 때까지 줄을 제거하십시오. WriteChar를 제거하십시오. ReadChar를 EAX에 대한 간단한 할당으로 바꿉니다 (함수를 호출하고 좋은 입력을 되찾은 척한). AsciiToDigit에 대한 호출을 건너 뜁니다. 작동 될 때까지 프로그램을 자르십시오. 또한 "왜"가 아니라 "왜"를 기록해야합니다. "shift ebx left one"과 같은 코멘트는'shl ebx, 1'이하는 일이 명확하기 때문에 쓸모가 없습니다. 하지만 * 왜 * ebx가 1 씩 왼쪽으로 이동하고 있습니까? – indiv

답변

0

지금까지 볼 수있는 몇 가지 사항이 있습니다.

첫 번째 부분에서 기본 숫자를 가져 오려고하면 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 

EAX에서 61h를 빼면 사람이 "Enter"를 누르면 해당 값이 사라집니다. 의미 13h는 61h로 뺀 다음 AL을 ACh로 남겨 둡니다. 이 모든 것은 코드가 연속적으로 61h를 감산하는 한 입력란에서 13h를 보지 못할 것임을 의미합니다.

여러분은 좀 더 cmp를 넣고이 점에 관해 좀 더 생각해 보시기 바랍니다. 또한, 스택에 밀고 팝하는 것에주의하십시오. 레지스터를보고 해당 기능을 수행 할 때 수행 한 작업을 확인하십시오.

살펴보고 도움이되기를 바랍니다.