x86-64汇编输入验证问题:末尾校验致首字符值异常
Fixing Your Assembly Input Validation Bug
Hey there, let's break down exactly why your code is mangling the first character when checking the end of the input, and get it working right.
The Root Cause
Your logic for grabbing the last character of the input is completely off—this is why the first character gets corrupted:
mov al, [character] ; You load the first character into al add rax, r8 ; Then you add the input length (r8) to rax!
This isn't calculating the memory address of the last character—it's adding the length value directly to the ASCII value of the first character. That's why your first character gets messed up, and you're not actually checking the real last character at all.
How to Correctly Grab the Last Character
To validate the final character properly without touching the first one, you need to:
- Calculate the memory address of the last input byte:
character + number_of_bytes_read - 1 - Load the value from that address into a separate register
- Run your validation checks on that new value
Fixed Full Code
section .data text1 db "ENTER TEXT: " len_text1 equ $ - text1 text2 db "THIS IS WHAT YOU ENTERED: " len_text2 equ $ - text2 text3 db "invalid message, keeping current " len_text3 equ $ - text3 section .bss character resb 255 section .text global main main: ; Print input prompt mov rax, 1 mov rdi, 1 mov rsi, text1 mov rdx, len_text1 syscall call validate validate: ; Read user input from stdin mov rax, 0 mov rdi, 0 mov rsi, character mov rdx, 10 syscall mov r8, rax ; Store number of bytes read in r8 ; Validate first character is uppercase A-Z mov al, [character] cmp al, 'A' jl invalid cmp al, 'Z' jg invalid ; Calculate address of the last input character mov rbx, character add rbx, r8 sub rbx, 1 ; rbx now points to the final byte of input mov cl, [rbx] ; Load last character into cl (separate from al) ; Check if last character is ! . or ? cmp cl, '!' je valid cmp cl, '.' je valid cmp cl, '?' je valid ; If we reach here, last character fails validation jmp invalid valid: ; Print confirmation prompt mov rax, 1 mov rdi, 1 mov rsi, text2 mov rdx, len_text2 syscall ; Print the valid user input mov rax, 1 mov rdi, 1 mov rsi, character mov rdx, r8 syscall jmp exit invalid: ; Print error message mov rax, 1 mov rdi, 1 mov rsi, text3 mov rdx, len_text3 syscall ; Print original input to "keep current message" mov rax, 1 mov rdi, 1 mov rsi, character mov rdx, r8 syscall jmp exit exit: mov rax, 60 xor rdi, rdi syscall
Key Fixes Explained
- Proper Last Character Addressing: We use
rbxas a pointer to calculate the exact memory location of the last input byte, so we never modify the first character's original value. - Dynamic String Lengths: Instead of hardcoding lengths like
12, we useequ $ - labelto calculate the exact length of each string. This fixes truncated error messages and makes the code more maintainable. - Cleaner Branch Logic: Split first-character and last-character validation into distinct steps, making the code easier to follow and debug.
- Full Requirement Compliance: The invalid branch now prints both the error message and the original input, which matches your requirement to "keep current message" when input is invalid.
内容的提问来源于stack exchange,提问作者Kadi
相关产品推荐
相关产品推荐

