有没有办法使用 printf 在 Linux 上的 NASM 汇编中打印递减十六进制数字的水平列表

问题描述 投票:0回答:1

我本质上想编写一个程序,接受 F 并将其递减直到为 0,显示结果如下:F E D C B A 9 8 7 6 5 4 3 2 1 0。我特别必须使用循环来写出这些,我可以'只需说“db 'F E D C B A 9 8 7 6 5 4 3 2 1', 10, 0”。由于我无法使用系统调用来打印(写入)十六进制数字,因此我放弃了这种思维方式。无论我走到哪里,我都被告知要使用 printf,因为它不需要从数字到字符的转换。然而, printf 似乎需要一个参数,该参数通常类似于标签中的“db '%x', 10, 0”。 10 通常是 LF 使得似乎不可能编写一个“水平”列表,而是编写一个我真的不想要的“垂直”列表。 所以我尝试参加这个课程: extern printf global main section .data format_specifier: db '%x', 10, 0 ;format specifier for printf with LF section .text main: mov rbx, qword 16 loop1: ;loop to decrement and print number in rsi dec rbx mov rdi, format_specifier mov rsi, rbx xor rax, rax call printf cmp rbx, qword 0 jne loop1 mov rax, 60 syscall

并将格式说明符中的 10 替换为 0x20(空格 ASCII),以在打印时分隔十六进制数字。当然,这不会导致任何输出。

我已经看到 LF 刷新了输出缓冲区,我尝试使用 fflush 来做同样的事情,但没有效果:

extern printf extern fflush global main section .data format_specifier: db '%x', 0x20, 0 ;format specifier for printf with LF section .text main: mov rbx, qword 16 loop1: ;loop to decrement and print number in rsi dec rbx mov rdi, format_specifier mov rsi, rbx xor rax, rax xor rsi, rsi call fflush call printf cmp rbx, qword 0 jne loop1 mov rax, 60 syscall

我不确定尝试在我的程序中使用 fflush 是否是正确的想法,或者我是否只是走错了方向。请帮忙。


您可以将

printf
linux assembly nasm
1个回答
0
投票
putchar

也是一件事。此外,您应该保持堆栈 16 字节对齐,并且使用退出系统调用是不好的做法。

一个可能的解决方案:
extern printf
extern putchar
global main

section .data

format_specifier:
  db '%X', 0x20, 0 ;format specifier for printf with trailing space

section .text

main:
    push rbx ; rbx is callee-saved. Also aligns stack.
    mov ebx, 15 ; 32 bits is enough

loop1: ;loop to decrement and print number in rsi 
    lea rdi, [rel format_specifier] ; use position independent code
    mov esi, ebx
    xor eax, eax ; 32 bit ops zero extend
    call printf wrt ..plt ; PIC
    dec ebx
    jns loop1
    mov edi, 10 ; LF
    call putchar wrt ..plt

    xor eax, eax ; exit code
    pop rbx
    ret

警告:这将在最后一个

0
 之后打印一个空格。

或者,您可以完全避免

printf

extern putchar global main main: push rbx ; rbx is callee-saved. Also aligns stack. mov ebx, 'F' loop1: ;loop to decrement and print number in rsi mov edi, ebx call putchar wrt ..plt ; PIC dec ebx cmp ebx, '0' jb done cmp ebx, 'A' - 1 jne space mov ebx, '9' space: mov edi, ' ' call putchar wrt ..plt jmp loop1 done: mov edi, 10 ; LF call putchar wrt ..plt xor eax, eax ; exit code pop rbx ret

    

© www.soinside.com 2019 - 2024. All rights reserved.