linux - 使用 YASM 程序集时如何更改 64 位 Linux 中的终端颜色?

标签 linux assembly x86-64 yasm

我试图根据用户输入的 1 到 5 的数字来更改终端的颜色,但它不起作用。

抱歉,我不太了解汇编,但需要为一个项目执行此操作,并且无法理解它有什么问题。

它只应该更改为我在代码中使用的颜色。它甚至没有重置终端颜色,所以我不知道如何让它工作。

section .data
    reset_color db "\033[0m"  ; ANSI escape code to reset colors
    bg_red db "\033[41m"     ; ANSI escape code for red background color
    bg_green db "\033[42m"   ; ANSI escape code for green background color
    bg_yellow db "\033[43m"  ; ANSI escape code for yellow background color
    bg_blue db "\033[44m"    ; ANSI escape code for blue background color
    bg_magenta db "\033[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

最佳答案

喜欢Jester showed in a comment ,您可以在 db 行中将 \033 写为文字数字 27:

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

然后你的程序就可以运行了,但是它仍然重复运行!
通过在转义序列中使用占位符,您可以轻松地极大地简化此代码(我使用了问号)。一旦用户提供了有效的数字“1”到“5”,您只需将其复制到占位符上并输出批处理即可。无需先将数字字符转换为其数值。

    ; 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

关于linux - 使用 YASM 程序集时如何更改 64 位 Linux 中的终端颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76353881/

相关文章:

x86-64 - 为什么x86-64系统只有48位虚拟地址空间?

assembly - 为什么我们使用 sub $0x18, %rsp?

linux - 应用 CPU Hogs 时的 Docker 和 CPU 优先级

linux - 在 linux ubuntu 中使用 CPAN 时,我应该使用 sudo/作为 root 还是作为我的默认用户运行它

c++ - VSCode - C++ 未定义对 'CLASS::FUNCTION' 的引用

从 bootloader 调用 32 位或 64 位程序

c - 为什么编译器在这种情况下使用 32 位寄存器将指针传递给 amd64 linux 上的函数

linux - 如何在 Linux 中水平打印 awk 输出

assembly - Sprite 运动的正弦函数的替代方案

c - x64 assembly 部门