Assembly 如何检查用户输入的结尾是否以“结束”'&引用&引用&“&引用;

Assembly 如何检查用户输入的结尾是否以“结束”'&引用&引用&“&引用;,assembly,x86-64,nasm,Assembly,X86 64,Nasm,从用户处获取新消息。验证邮件,以确保邮件以大写字母开头,以句点(“.”)、问号(“?”)或感叹号(“!”)结尾。如果输入无效,则拒绝输入,并向用户发送错误消息(继续使用先前的消息)。否则,如果有效,则替换原始消息 我检查第一个有效的字符,现在要检查字符串的结尾,我将输入字符的长度加上输入减去1。但这会改变用户输入的第一个字符的值 section .data text1 db "ENTER TEXT: " len equ $ - text1 text

从用户处获取新消息。验证邮件,以确保邮件以大写字母开头,以句点(“.”)、问号(“?”)或感叹号(“!”)结尾。如果输入无效,则拒绝输入,并向用户发送错误消息(继续使用先前的消息)。否则,如果有效,则替换原始消息

我检查第一个有效的字符,现在要检查字符串的结尾,我将输入字符的长度加上输入减去1。但这会改变用户输入的第一个字符的值

section .data
        text1 db "ENTER TEXT: "
        len equ $ - text1
        text2 db "THIS IS WHAT YOU ENTERED: "
        text3 db "invalid message, keeping curent "


section .bss
        character resb 255

section .text
        global main

main:
        mov r11, text2

        mov rax, 1
        mov rdi, 1
        mov rsi, text1
        mov rdx, 12
        syscall
        call validate


validate:

         mov rax, 0
        mov rdi, 0
        mov rsi, character
        mov rdx, 10
        syscall                                                                                                                                                                
        mov r8, rax

        mov rdi, character
        mov al, [character]
        mov ah, 'A'
        cmp al, ah
        jl invalid

        cmp al, 90
        jg invalid

        add rax, r8             ;                                                                                                                                                                           
        sub rax, 1

        cmp rax, '!'
        je valid
        cmp rax, '.'
        je valid
        cmp rax, '?'
        je valid
valid:

        mov r11, character

        mov rax, 1
        mov rdi, 1
        mov rsi, r11
        mov rdx, r8
        syscall
        jmp exit

invalid:

        mov rax, 1
        mov rdi, 1
        mov rsi, text3
        mov rdx, 12
        syscall
        jmp exit

exit:

        mov rax, 60
        xor rdi, rdi
        syscall

考虑简化代码,同时不更改用户条目。SYSCALL已经返回了您输入的字符数,并且RSI保持不变

mov  cl, [rsi]      ; RSI already points to first character
cmp  cl, 'A'
jb  invalid
cmp  cl, 'Z'
ja  invalid

mov  al, [rsi+rax-2]    ; RAX = # of characters entered

cmp  al, '.'
jz  valid
cmp  al, '?'
jz  valid
cmp  al, '!'
jnz Error

现在,由于没有不必要地设置其他指针,所以没有更改前导字符并节省了几个字节。

您将地址加载到
rdi
not
rax
。将其更改为
rax
,并将分配移动到
添加
之前。此外,您需要从内存中提取字符,即在比较中使用
cmp byte[rax]
。您可以使用
movd xmm0、eax
/
pshufd xmm0、xmm0
(将字节复制到4个DWORD中的每一个的底部)检查字符是否为最多4个值之一。然后
pcmpeqb xmm0,[rel compare_vector]
/
pmovmkb eax,xmm0
以获得位图比较结果。然后
测试eax,0x1111
以测试每组4的低位元素,查看其中是否有非零。(x86-64包括SSE2作为基线)。无论如何,这回答了有趣的标题问题,但不是调试问题,所以我没有将其作为答案发布。