英文:
How can I change the terminal color in 64-bit Linux when using YASM assembly?
问题
section .data
reset_color db "3[0m" ; ANSI escape code to reset colors
bg_red db "3[41m" ; ANSI escape code for red background color
bg_green db "3[42m" ; ANSI escape code for green background color
bg_yellow db "3[43m" ; ANSI escape code for yellow background color
bg_blue db "3[44m" ; ANSI escape code for blue background color
bg_magenta db "3[45m" ; ANSI escape code for magenta background color
section .bss
number resb 1 ; Variable to store the user-selected number
section .text
global _start
_start:
; Reset terminal attributes
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, reset_color
mov rdx, 4 ; length of the string
syscall
; Display a prompt to enter a number
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, prompt
mov rdx, prompt_len
syscall
; Read the user input
mov rax, 0 ; sys_read
mov rdi, 0 ; stdin
mov rsi, number
mov rdx, 1 ; read one byte
syscall
; Convert the input to a number
movzx eax, byte [number]
sub eax, '0'
; Change the background color based on the selected number
cmp eax, 1
je change_to_red
cmp eax, 2
je change_to_green
cmp eax, 3
je change_to_yellow
cmp eax, 4
je change_to_blue
cmp eax, 5
je change_to_magenta
; Invalid input, display an error message
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, error_message
mov rdx, error_message_len
syscall
jmp exit_program
change_to_red:
; Change the background color to red
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_red
mov rdx, 5 ; length of the string
syscall
jmp exit_program
change_to_green:
; Change the background color to green
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_green
mov rdx, 5 ; length of the string
syscall
jmp exit_program
change_to_yellow:
; Change the background color to yellow
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_yellow
mov rdx, 5 ; length of the string
syscall
jmp exit_program
change_to_blue:
; Change the background color to blue
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_blue
mov rdx, 5 ; length of the string
syscall
jmp exit_program
change_to_magenta:
; Change the background color to magenta
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_magenta
mov rdx, 5 ; length of the string
syscall
exit_program:
; Exit the program
mov rax, 60 ; sys_exit
xor rdi, rdi ; exit code 0
syscall
section .data
prompt db "Enter a number (1-5): ", 0
prompt_len equ $-prompt
error_message db "Invalid input!", 0
error_message_len equ $-error_message
英文:
Im trying to change the colour of the terminal based on a number of 1 to 5 inputed by the user but it just doesnt work.
Sorry i dont really understand assembly but need to do this for a project and cant understand what is wrong with it.
Its only supposed to change to this colors that i use in the code. It doesnt even reset the terminal color so i dont know how to make it work.
section .data
reset_color db "3[0m" ; ANSI escape code to reset colors
bg_red db "3[41m" ; ANSI escape code for red background color
bg_green db "3[42m" ; ANSI escape code for green background color
bg_yellow db "3[43m" ; ANSI escape code for yellow background color
bg_blue db "3[44m" ; ANSI escape code for blue background color
bg_magenta db "3[45m" ; ANSI escape code for magenta background color
section .bss
number resb 1 ; Variable to store the user-selected number
section .text
global _start
_start:
; Reset terminal attributes
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, reset_color
mov rdx, 4 ; length of the string
syscall
; Display a prompt to enter a number
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, prompt
mov rdx, prompt_len
syscall
; Read the user input
mov rax, 0 ; sys_read
mov rdi, 0 ; stdin
mov rsi, number
mov rdx, 1 ; read one byte
syscall
; Convert the input to a number
movzx eax, byte [number]
sub eax, '0'
; Change the background color based on the selected number
cmp eax, 1
je change_to_red
cmp eax, 2
je change_to_green
cmp eax, 3
je change_to_yellow
cmp eax, 4
je change_to_blue
cmp eax, 5
je change_to_magenta
; Invalid input, display an error message
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, error_message
mov rdx, error_message_len
syscall
jmp exit_program
change_to_red:
; Change the background color to red
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_red
mov rdx, 5 ; length of the string
syscall
jmp exit_program
change_to_green:
; Change the background color to green
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_green
mov rdx, 5 ; length of the string
syscall
jmp exit_program
change_to_yellow:
; Change the background color to yellow
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_yellow
mov rdx, 5 ; length of the string
syscall
jmp exit_program
change_to_blue:
; Change the background color to blue
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_blue
mov rdx, 5 ; length of the string
syscall
jmp exit_program
change_to_magenta:
; Change the background color to magenta
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, bg_magenta
mov rdx, 5 ; length of the string
syscall
exit_program:
; Exit the program
mov rax, 60 ; sys_exit
xor rdi, rdi ; exit code 0
syscall
section .data
prompt db "Enter a number (1-5): ", 0
prompt_len equ $-prompt
error_message db "Invalid input!", 0
error_message_len equ $-error_message
答案1
得分: 2
就像Jester在评论中所示 ,您可以在db
行中将\033
写为文字数字27:
section .data
reset_color db 27, "[0m" ; ANSI转义代码以重置颜色
bg_color db 27, "[4?m" ; ANSI转义代码用于???背景颜色
^
\ ? 是一个占位符
然后您的程序将正常工作,但仍然存在自我重复的问题!
您可以通过在转义序列中使用占位符(我使用了问号)来极大简化此代码。一旦用户提供了有效的数字'1'到'5',您只需将其复制到占位符上并输出即可。无需先将数字字符转换为其数字值。
; 读取用户输入
mov eax, 0 ; sys_read
mov edi, 0 ; stdin
mov rsi, number
mov edx, 1 ; 读取一个字节
syscall
; 修补转义序列并将其写入
mov rsi, error_message
mov edx, error_message_len
movzx eax, byte [number]
cmp al, '1'
jb WriteMsg
cmp al, '5'
ja WriteMsg
mov rsi, bg_color
mov edx, 5 ; 字符串的长度
mov [rsi + 3], al ; 这将覆盖占位符
; 更改背景颜色或显示错误消息
WriteMsg:
mov eax, 1 ; sys_write
mov edi, 1 ; stdout
syscall
exit_program:
; 退出程序
mov eax, 60 ; sys_exit
xor edi, edi ; 退出代码 0
syscall
英文:
Like Jester showed in a comment, you can write that \033
as the literal number 27 in the db
lines:
section .data
reset_color db 27, "[0m" ; ANSI escape code to reset colors
bg_color db 27, "[4?m" ; ANSI escape code for ??? background color
^
\ ? is a placeholder
Your program will work then, but it still suffers from repeating itself!
You can easily simplify this code enormously by using a placeholder in the escape sequence (I used the question mark). And once the user supplies a valid digit '1' through '5', you just copy it over the placeholder and output the lot. No need to first convert the digit character into its number value.
; Read the user input
mov eax, 0 ; sys_read
mov edi, 0 ; stdin
mov rsi, number
mov edx, 1 ; read one byte
syscall
; Patch escape sequence and write it
mov rsi, error_message
mov edx, error_message_len
movzx eax, byte [number]
cmp al, '1'
jb WriteMsg
cmp al, '5'
ja WriteMsg
mov rsi, bg_color
mov edx, 5 ; length of the string
mov [rsi + 3], al ; This overwrites the placeholder
; Changes the background color OR displays error message
WriteMsg:
mov eax, 1 ; sys_write
mov edi, 1 ; stdout
syscall
exit_program:
; Exit the program
mov eax, 60 ; sys_exit
xor edi, edi ; exit code 0
syscall
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论