如何在使用 YASM 汇编时更改 64 位 Linux 终端颜色?

huangapple go评论61阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年5月29日 06:50:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76353881.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定