汇编中没有换行符的 Printf
我最近读过这篇关于在汇编中使用 printf 和 scanf 的文章:
汇编中 intfmt: db "%d", 10, 0 的含义
特别是它说 “在 printf 中,换行符打印一个换行符,然后(如果输出处于行缓冲模式,这可能是),刷新内部输出缓冲区,以便您实际上可以看到结果。因此,当您删除 10 时,没有刷新而且你看不到输出。”
但是,如果我不想在汇编文件中的输出后添加换行符,我不知道该怎么办。 这是我编写的一个简单的测试文件,用于尝试在没有换行符的情况下进行打印:
extern printf
LINUX equ 80H ; interupt number for entering Linux kernel
EXIT equ 60 ; Linux system call 1 i.e. exit ()
section .data
int_output_format: db "%ld", 0
segment .text
global main
main:
mov r8, 10
push rdi
push rsi
push r10
push r9
mov rsi, r8
mov rdi, int_output_format
xor rax, rax
call printf
pop r9
pop r10
pop rsi
pop rdi
call os_return ; return to operating system
os_return:
mov rax, EXIT ; Linux system call 1 i.e. exit ()
mov rdi, 0 ; Error code 0 i.e. no errors
syscall ; Interrupt Linux kernel 64-bit
但正如我读过的文章表明 stdout 没有被刷新。我在想也许我需要在输出数字后以某种方式刷新?但我真的不确定。
我正在使用 NASM 汇编语言。
提前致谢!
I've recently read this article on using printf and scanf in assembly:
Meaning of intfmt: db "%d", 10, 0 in assembly
In particular it says
"In printf, the newline prints a newline and then (if the output is in line buffered mode, which it probably is), flushes the internal output buffer so you can actually see the result. So when you remove the 10, there's no flush and you don't see the output."
However I do not know what to do if I do not want a newline after my output in my assembly file.
Here's a simple test file I've written to try printing without a newline:
extern printf
LINUX equ 80H ; interupt number for entering Linux kernel
EXIT equ 60 ; Linux system call 1 i.e. exit ()
section .data
int_output_format: db "%ld", 0
segment .text
global main
main:
mov r8, 10
push rdi
push rsi
push r10
push r9
mov rsi, r8
mov rdi, int_output_format
xor rax, rax
call printf
pop r9
pop r10
pop rsi
pop rdi
call os_return ; return to operating system
os_return:
mov rax, EXIT ; Linux system call 1 i.e. exit ()
mov rdi, 0 ; Error code 0 i.e. no errors
syscall ; Interrupt Linux kernel 64-bit
but as the article I've read suggests stdout isn't being flushed. I was thinking perhaps I need to somehow flush after I output the number? But I'm really not sure.
I am using the NASM assembly language.
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
fflush() 刷新行缓冲或全缓冲的输出stdio 流:
或者,
mov rdi, [stdout]
/call fflush
也可以仅刷新该流。 (使用default rel
来实现高效的 RIP 相对寻址,并且您还需要extern stdout
。)fflush() flushes buffered output in line or full-buffered stdio streams:
Alternatively,
mov rdi, [stdout]
/call fflush
also works to flush only that stream. (Usedefault rel
for efficient RIP-relative addressing, and you'll needextern stdout
as well.)调用 fflush(stdout); 来显示缓冲区中当前的内容。
Call
fflush(stdout);
to display what's currently sitting in the buffers.对于 Windows 32 位模式 (FASM):
GNU/Linux 32 位模式 (NASM)
For Windows 32-bit mode (FASM):
GNU/Linux 32-bit mode (NASM)
另一种可能性是删除 stdout 流的默认行缓冲。这里 C 调用来做到这一点。翻译成汇编让作为练习,因为我认为在 ASM 中进行文件/流 I/O 甚至没有意义,成本/收益是非常错误的。
这样,每个 printf(以及 fputs、putc、puts 等)都会有一个隐式的
fflush
The other possibility would be to remove the default line buffering of the
stdout
stream. Here the C call to do that. Translation to assembly let as exercice, as I don't think it makes even sense to do file/stream I/O in ASM, the cost/benefit is tremendously wrong.This way every
printf
(andfputs
,putc
,puts
etc...) would have an implicitfflush
我的答案是针对那些寻求快速绕过问题而不是实际解决方案的人。
我试图一次输出一位数字 1234,并遇到了与此处相同的问题。在使用上述解决方案没有成功之后,并且不想在这方面花费超过几分钟的时间,我找到了一种显示数字的简单方法。
在输出字符串格式中,只需有一个空行的输出字符串(当然还有换行符)。
随心所欲地输出;就我而言,我有 4 次 digital_out 推送(其中 4 次数字本身推送)和 4 次 printf 调用。
完成后,按下 Number_end 并最后调用 printf。然后将显示整个数字:)
My answer is for those searching a fast bypass to the problem, not an actual fix.
I was attempting to output the number 1234 one digit at a time and encountered the same issue as those here. After having no success with the mentioned solutions, and not wanting to spend more than a few minutes on this, I have found an easy way to display the number.
In your output string formats, simply have an output string that is an empty line (with the newline ofcourse).
Output as you would; in my case I had 4 pushes of digit_out (with 4 pushes of the digits themselves) and 4 calls to printf.
Once this is done, push Number_end and do a final call to printf. The entire number will then show :)