2013-03-04 78 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