我本质上想编写一个程序,接受 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
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