Преобразование символов в код ASCII (десятичный) в ассемблере

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

Когда я ввожу в подсказку «a», мой эмулятор показывает, что моя переменная char хранит 61 шестнадцатеричное число, что правильно. Я просто не могу заставить его печатать на экране (в шестнадцатеричном или десятичном формате).

РЕДАКТИРОВАТЬ: ИЗМЕНЕН КОД, ЧТОБЫ ПОВЕРНУТЬ И РАЗДЕЛИТЬ НА ДЕСЯТЬ. У МЕНЯ ПЕЧАТАЮТСЯ ПРАВИЛЬНЫЕ СИМВОЛЫ, НО В ОБРАТНОМ. ЦИФРА 97 ПЕЧАТАЕТ 79

Пока это то, что у меня есть:

; **************** MACROS *********************

; START PROGRAM
START MACRO

    MOV AX, DATA ; Data Segment to AX Register
    MOV DS, AX   ; HAVE DS Point to Data Segment  
ENDM          

; END PROGRAM
END MACRO  

    MOV AH, 4CH  ; END Program
    INT 21H      ; Call DOS Service
ENDM

; PRINT STRING TO OUTPUT        
PSTRING MACRO STR

    MOV AH,09H
    LEA DX,STR
    INT 21H
ENDM

; Creates a New Line
NEWLINE MACRO 
    MOV DX, 0AH   ; Input of string to DX
    MOV AH, 02H   ; Write Char to standard output
    INT 21H        

    MOV DL, 0DH   ; 
    MOV AH, 02H   ; Carriage Return
    INT 21H       ;
ENDM

; Get CHAR Input 
GETINPUT MACRO INPUT

    MOV AH, 01H     ; Receive input          
    INT 21H         ; Call DOS Service

    MOV INPUT, AL   ; Store into Input Variable  
ENDM 

; ********** END MACROS *******************


.MODEL   
.DATA   

   MSG1 db 'Choose A Char to Convert To ASCII: $' 
   CHAR db ?   ; Store Input Char
   REM  db ?   ; Remainder 8-bit storate
   QUOT db ?   ; Quotient  8-bit storage

.CODE 

  MAIN PROC 

    START 

    PSTRING MSG1 

    GETINPUT CHAR

    NEWLINE       

    MOV AX, 0     ; Clear AX Register
    MOV AL, CHAR  ; Move input to AL 

    MOV DX, 0     ; Clear DX Register
    MOV DL, 10    ; Add 10 to DL Register
    DIV DL        ; Divide By Number of Students For Average   

    ; ********************** ;
    ; QUOTIENT  STORED IN AL ;
    ; REMAINDER STORED IN AH ;
    ; ********************** ;                                               


    myLoop:  

        MOV REM, AH   ; Move Remainder into REM  Variable
        MOV QUOT, AL  ; Move Quotient  into QUOT Variable

        MOV DL, REM  ; Move Data we want printed into DL
        ADD DL, '0'   ; Make into Ascii Char

        MOV AH,02H    ; Output Char Service
        INT 21H       ; Call DOS Service


        MOV AL, QUOT  ; Place Quotient Into AL
        MOV AH, 0     ; AH was altered, Zero it out

        MOV DL, 10    ; Set Divisor to 10
        DIV DL        ; Divide AX by 10

        CMP AH, 0     ; If No Quotient Remains we can exit 

    JNZ myLoop        ; Jump if NOT zero 


    MOV AH, 4CH       ; End Program
    INT 21H     

    END               

  MAIN ENDP   
END MAIN

person Community    schedule 10.04.2016    source источник
comment
Ваш PSTRING макрос использует int 21h/ah=9 для вывода на консоль. Из ссылки вы увидите, что строка должна заканчиваться $. Что вы можете сделать, так это поместить $ в память сразу после места, в которое вы записываете свой символ. Вы сможете сделать это, изменив CHAR db ? на CHAR db ?, '$' . Это должно решить проблему отображения мусора.   -  person Michael Petch    schedule 10.04.2016
comment
Это решает одну проблему, лол. Основная проблема — это то, над чем я сейчас работаю. Взгляните на мой пересмотренный код. Я сделал цикл, чтобы разделить шестнадцатеричное число на 10, а затем вывести каждое число. Проблема в том, что мой номер выходит esrever... извините, я имею в виду наоборот. Например, я могу получить значение для «а» равным 97, но получается 79.   -  person    schedule 10.04.2016
comment
Я не вижу вашего кода для этого, но я понимаю, что вы многократно выполняете деление на 10. Он выходит задом наперед, потому что вы обрабатываете числа от младших значащих цифр до самых значащих цифр. Есть несколько способов справиться с этим, и если вы посмотрите, есть несколько примеров даже на StackOverflow (один основан на стеке, а другой - записывать символы в выходной буфер, сохраняя их справа налево)   -  person Michael Petch    schedule 10.04.2016
comment
@MichaelPetch Забыл указать ваше имя, чтобы вы увидели ответ. Спасибо за ваше время Майкл   -  person    schedule 10.04.2016
comment
@MichaelPetch (извините, редактирование заняло больше времени, чем я думал) Большинство методов push/pop, которые я видел, сводят число к нулю, но при попытке сделать это всегда возникают ошибки. В любом случае вы можете показать мне пример push/pop в 8086. Я продолжу искать   -  person    schedule 10.04.2016
comment
Вот один из методов, который использует буфер (не push pop): stackoverflow.com/a/15621644/3857942 . Код, на который я ссылаюсь, предназначен для NASM, но общая идея должна использоваться с небольшими изменениями для работы с EMU8086.   -  person Michael Petch    schedule 10.04.2016


Ответы (1)


Хорошо, я решил это. Вот окончательный код. Пожалуйста, помните, что я всего лишь новичок - так что не рвите мне новый, если этот код плохой. Однако это работает!

; **************** MACROS *********************

; START PROGRAM
START MACRO

    MOV AX, DATA ; Data Segment to AX Register
    MOV DS, AX   ; HAVE DS Point to Data Segment  
ENDM          

; END PROGRAM
END MACRO  

    MOV AH, 4CH  ; END Program
    INT 21H      ; Call DOS Service
ENDM

; PRINT STRING TO OUTPUT        
PSTRING MACRO STR

    MOV AH,09H
    LEA DX,STR
    INT 21H
ENDM

; Creates a New Line
NEWLINE MACRO 
    MOV DX, 0AH   ; Input of string to DX
    MOV AH, 02H   ; Write Char to standard output
    INT 21H        

    MOV DL, 0DH   ; 
    MOV AH, 02H   ; Carriage Return
    INT 21H       ;
ENDM

; Get CHAR Input 
GETINPUT MACRO INPUT

    MOV AH, 01H     ; Receive input          
    INT 21H         ; Call DOS Service

    MOV INPUT, AL   ; Store into Input Variable  
ENDM 

; ********** END MACROS *******************


.MODEL

.STACK 100H

.DATA 

   MSG1 db 'Choose A Char to Convert To ASCII: $' 
   CHAR db ?   ; Store Input Char
   REM  db ?   ; Remainder 8-bit storate
   QUOT db ?   ; Quotient  8-bit storage
   COUNT db 0  ; Counts the stacks  

.CODE 

  MAIN PROC 

    START 

    PSTRING MSG1 

    GETINPUT CHAR

    NEWLINE       

    MOV AX, 0     ; Clear AX Register
    MOV AL, CHAR  ; Move input to AL 

    MOV DX, 0     ; Clear DX Register

    ; ********************** ;
    ; QUOTIENT  STORED IN AL ;
    ; REMAINDER STORED IN AH ;
    ; ********************** ;                                               


    myLoop:  

        MOV DL, 10    ; Set Divisor to 10
        DIV DL        ; Divide AX by 10

        MOV REM, AH   ; Move Remainder into REM  Variable
        MOV QUOT, AL  ; Move Quotient  into QUOT Variable

        MOV AX, 0     ; Clear AX
        MOV AL, REM   ; Move REM to AL
        PUSH AX       ; Push AX to Stack
        INC COUNT     ; Increase Count by 1

        MOV AL, QUOT  ; Place Quotient Into AL
        MOV AH, 0     ; AH was altered, Zero it out

        CMP AL, 0     ; If No Quotient Remains we can exit 

    JNZ myLoop        ; Jump if NOT zero 

    myLoop2:  

        POP DX        ; Pop from the stack into DX

        ADD DX, '0'   ; To Ascii Char
        MOV AH, 02H   ; Print Char Command
        INT 21H       ; Call to DOS System

        DEC COUNT     ; Decrement COUNT
        CMP COUNT, 0  ; Compare COUNT to 0


    JNZ myLoop2    

    END               

  MAIN ENDP   
END MAIN
person Community    schedule 10.04.2016