2013-03-04 62 views
2

基本上我想做的(這是一個任務)是有一個字符的用戶類型,然後顯示它是一個大寫/小寫字母,0-9小數,可打印符號或控制鍵。NASM解析Ascii字符顯示

不幸的是,儘管文檔給了我一個關於控制邏輯(if/else,loops等等)的想法,但實際上知道讓NASM做我想做的事情的命令令人沮喪,因爲幻燈片和班級筆記,而且文件並不完全具有建設性。

控制鍵,我相信是ESC,空,標籤等從DEC 0〜32

在下面我的代碼,我接受來自用戶的輸入,但我不認爲它接受控制鍵,怎麼樣我會撥弄它嗎?

segment .data 

    msg3 dw '10h' 
segment .bss 
; 
aChar resb 2 ; reserve 10 bytes for aChar 

segment .text 
    global _start 
_start: 


    ; ### Code for simple Input ### 
    mov eax, 3 ; select kernal call #3 
    mov ebx, 0 ; default input device 
    mov ecx, aChar ; pointer to aChar' 
    int 0x80 ; invoke kernal call to read 


    ; ### Code to spit the input to the screen ### 
    mov eax, 4 ; select kernal call #4 
    mov ebx, 1  ; default output device 
    mov ecx, aChar ; pointer to ID 
    int 0x80 ; write id read 

    ; termination code 
exit: mov ax, 1 ; select system call #1 system exit 
    mov bx, 0 ; 0 means normal 
    int 0x80 ; invoke kernal call 

所以我在想,假設我能夠接受ascii中的控制鍵。是一旦用戶輸入一個字符,我將它轉換爲十六進制或十進制數,以較容易的爲準,然後運行,如果其他情況下,其中如果它的某個值之間它的X,然後顯示X,如果它介於兩個不同的值之間它的Y等等。因爲小於33的東西顯然是一個控制鍵,我認爲(DEL是一個控制鍵?它的DEC 127),但是小於48的任何符號都是我認爲的符號,但它也必須大於32,或者我只是假設它是否大於32,但小於48,假設符號?令人討厭的是,一切似乎都棲息在ASCII圖表的不同部分。

下面是將ASCII轉換爲HEX的代碼,我認爲小數可能更容易處理,但我不知道如何a)弄清楚即使我在註冊表某處有ascii字符的二進制值和b)將其轉換爲十進制,因爲我有這個代碼不妨使用它?

;Hex equivalent of characters    HEX2CHAR.ASM 
; 
;  Objective: To print the hex equivalent of 
;     ASCII character code. Demonstrates 
;     the use of xlat instruction. 
;   Input: Requests a character from the user. 
;   Output: Prints the ASCII code of the 
;     input character in hex. 
%include "io.mac" 

.DATA 
char_prompt db "Please input a character: ",0 
out_msg1  db "The ASCII code of '",0 
out_msg2  db "' in hex is ",0 
query_msg  db "Do you want to quit (Y/N): ",0 
; translation table: 4-bit binary to hex 
hex_table  db "ABCDEF"  

.CODE 
    .STARTUP 
read_char: 
    PutStr char_prompt ; request a char. input 
    GetCh AL   ; read input character 

    PutStr out_msg1 
    PutCh AL 
    PutStr out_msg2 
    mov  AH,AL  ; save input character in AH 
    mov  EBX,hex_table; EBX = translation table 
    shr  AL,4   ; move upper 4 bits to lower half 
    xlatb    ; replace AL with hex digit 
    PutCh AL   ; write the first hex digit 
    mov  AL,AH  ; restore input character to AL 
    and  AL,0FH  ; mask off upper 4 bits 
    xlatb 
    PutCh AL   ; write the second hex digit 
    nwln 
    PutStr query_msg ; query user whether to terminate 
    GetCh AL   ; read response 

    cmp  AL,'Y'  ; if response is not 'Y' 
    jne  read_char ; read another character 
done:      ; otherwise, terminate program 
    .EXIT 

從「Linux指令到彙編編程」。

我的查詢是,如果代碼將其轉換爲十六進制,它實際上是在內存中的十六進制?或者它只是顯示爲十六進制的ascii字符表示形式?如果是這樣,那顯然不能幫助我。

所以我的問題是爲了:

1.How我接受控制鍵的用戶輸入。 2.我如何解析ascii以便我在內存中註冊某個地方,我認爲這是一種奇怪的方式,用於說明我輸入的ASCII字符的HEX值爲「變量」?然後我可以調整並評估顯示我需要顯示的內容?

編輯:我想我找到了解決辦法,問題是它不工作,我不知道爲什麼:

decimal: 
    mov ebx, 30h ; smallest decimal ASCII 
    mov edx, key 
    cmp edx, ebx 
    jl uppercase 
    mov ebx, 39h ; test against 9 
    cmp edx, ebx 
    jg exit 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, decimalKey 
    mov edx, decimalLen 
    int 0x80 

它只是跳轉到「退出」評價爲「大於」每時間,無論我輸入什麼。

回答

2

終於想出來了。

; 
; This is assignment 2, it takes key strokes from the user 
; and displays whether it is a control key, upper case, 
; lower case, a printable symbol, or a decimal. 
; By Blayne Elison Bradley, 9688994 
; March 4th 2013 

segment .data 
    msg db 'Enter a character: ', 0xA ; text message 
    len equ $-msg               ; length of msg 
    msg2 db 'Your character is: ' ; text message 
    len2 equ $-msg2 

    controlKey: db "Control Key", 10 
    controlLen: equ $-controlKey 

    control2Key: db "ControlKey2", 10 
    control2Len: equ $-control2Key 

    printableKey: db "Printable", 10 
    printableLen: equ $-printableKey 

    printable2Key: db "Printable-2", 10 
    printable2Len: equ $-printable2Key 

    printable3Key: db "Printable-3", 10 
    printable3Len: equ $-printable3Key 

    printable4Key: db "Printable-4", 10 
    printable4Len: equ $-printable4Key 

    decimalKey: db "Decimal", 10 
    decimalLen: equ $-decimalKey 

    upperKey: db "Upper Case", 10 
    upperLen: equ $-upperKey 

    lowerKey: db "Lower Case", 10 
    lowerLen: equ $-lowerKey 

    smallerKey: db "Smaller", 10 
    smallerLen: equ $-smallerKey 

    biggerKey: db "Bigger", 10 
    biggerLen: equ $-biggerKey 

segment .bss 
; 
aChar resb 8 ; reserve 8 bytes for aChar 
; I changed the above to 8 and that seems to work with the code below, 
; I don't know if its crucial to its execution. 

segment .text 
     global _start 
_start: 

    ; ### Code for Outputting a simple Message ### 
    mov eax, 4 ; select kernal call #4 
    mov ebx, 1 ; default output device 
    mov ecx, msg ; second argument; pointer to message 
    mov edx, len ; third argument: length 
    int 0x80 ; invoke kernal call to write 

    mov eax, 3 ; select kernal call #3 
    mov ebx, 0 ; default input device 
    mov ecx, aChar ; pointer to aChar' 
    int 0x80 ; invoke kernal call to read 

control: ; is it a control key? 
    mov al, [aChar] ; 
    cmp al, 1Fh 
    jg printable 

    ; Output 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, controlKey 
    mov edx, controlLen 
    int 0x80 
    jmp exit ; because duh 

decimal:  
    mov al, [aChar] ; 
    cmp al, '9' 
    jg printable2 

    ; Output 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, decimalKey 
    mov edx, decimalLen 
    int 0x80  
    jmp exit 

printable: 
    mov al, [aChar] ; 
    cmp al, '/' 
    jg decimal 

    ; Output 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, controlKey 
    mov edx, controlLen 
    int 0x80 
    jmp exit ; because duh 

printable2: 
    mov al, [aChar] ; 
    cmp al, '@' 
    jg uppercase 

    ; Output 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, printable2Key 
    mov edx, printable2Len 
    int 0x80 
    jmp exit ; because duh 

uppercase: 
    mov al, [aChar] ; 
    cmp al, 'Z' 
    jg printable3 

    ; Output 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, upperKey 
    mov edx, upperLen 
    int 0x80 
    jmp exit ; because duh 

printable3: 
    mov al, [aChar] ; 
    cmp al, '`' 
    jg lowercase 

    ; Output 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, printable3Key 
    mov edx, printable3Len 
    int 0x80 
    jmp exit ; because duh 

lowercase: 
    mov al, [aChar] ; 
    cmp al, 7Ah 
    jg printable4 

    ; Output 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, lowerKey 
    mov edx, lowerLen 
    int 0x80 
    jmp exit ; because duh 

printable4: 
    mov al, [aChar] ; 
    cmp al, '~' 
    jg control2 

    ; Output 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, printable4Key 
    mov edx, printable4Len 
    int 0x80 
    jmp exit ; because duh 

control2: ; is it a control key? 
    mov al, [aChar] ; 
    cmp al, 7Fh 
    jg exit ; beyond range 

    ; Output 
    mov eax, 4 
    mov ebx, 1 
    mov ecx, control2Key 
    mov edx, control2Len 
    int 0x80 
    jmp exit ; because duh 

exit: 
    mov eax, 1 
    xor ebx, ebx 
    int 0x80 
+0

不要忘記標記你的答案是正確的! – Mikhail 2013-03-04 23:46:52

+0

沒有讓我做對了。 :( – RaenirSalazar 2013-03-19 17:40:06