【问题标题】:NASM Parsing Ascii Characters to displayNASM 解析要显示的 Ascii 字符
【发布时间】:2013-03-04 05:01:17
【问题描述】:

基本上我想要做的(这是一个分配)是让用户输入一个字符,然后显示它是大写/小写字母、0-9 十进制、可打印符号还是控件键。

不幸的是,虽然文档给了我一个关于摆弄控制逻辑(if/else、循环等)的想法,但实际上知道让 NASM 做我想做的事情的命令令人沮丧,因为幻灯片和类注释,并且文档并不完全具有建设性。

我认为控制键是从 DEC 0 到 32 的 esc、null、tab 等。

在我下面的代码中,我接受了用户的输入,但我认为它不接受控制键,我该怎么做呢?

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 中的控制键。是不是一旦用户输入了一个字符,我将它转换为十六进制或十进制,以更容易者为准,然后运行 ​​if else case 如果它在某些值之间是一个 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  "0123456789ABCDEF"    

.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.如何接受用户输入的控制键。 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

无论我输入什么,它每次都会跳转到“退出”,评估为“大于”。

【问题讨论】:

    标签: parsing ascii nasm


    【解决方案1】:

    终于想通了。

    ;
    ; 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
    

    【讨论】:

      猜你喜欢
      • 2015-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2011-01-12
      • 1970-01-01
      • 2019-10-15
      相关资源
      最近更新 更多