gpt4 book ai didi

c - 在 Linux 上混合系统调用写入和 printf

转载 作者:IT王子 更新时间:2023-10-29 01:00:12 26 4
gpt4 key购买 nike

我在程序集调用 c 函数时做了一些测试,我得到了我认为在使用 ansi 转义码和调用使用 printf 的 c 函数时的奇怪行为。

这是 assembly 部分:

section .data               

red db 27,"[31;1m",0
redlen equ $ - red

cyan db 27,"[36;1m",0
cyanlen equ $ - cyan

colorReset db 27,"[0m",0
colorResetLen equ $ - colorReset

section .text

extern printLetter
extern letter

global main

main:
mov BYTE [letter], 'H'
call ansiSetRed
call printLetter
mov BYTE [letter], 'e'
call ansiSetCyan
call printLetter
mov BYTE [letter], 'l'
call ansiReset
call printLetter
mov BYTE [letter], 'l'
call ansiSetRed
call printLetter
mov BYTE [letter], 'o'
call ansiSetCyan
call printLetter
mov BYTE [letter], '!'
call ansiReset
call printLetter
mov BYTE [letter], 10
call printLetter

ret

ansiSetRed:
mov rax, 1
mov rdi, 1
mov rsi, red
mov rdx, redlen
syscall
ret

ansiSetCyan:
mov rax, 1
mov rdi, 1
mov rsi, cyan
mov rdx, cyanlen
syscall
ret

ansiReset:
mov rax, 1
mov rdi, 1
mov rsi, colorReset
mov rdx, colorResetLen
syscall
ret

看起来很长,但我所做的只是在开头定义一些带有 ANSI 代码的字符串,一个用于将前景色设置为红色,一个用于青色,一个用于重置颜色。

然后我有使用系统调用 write 打印此 ansi 字符串的函数。

main 函数只是应该打印“Hello!”交替每个字母的颜色,方法是首先调用打印相应 ansi 字符串的汇编函数,然后调用打印存储在全局变量中的字符的 extern c 函数。

这里是c部分:

#include <stdio.h>

char letter;

void printLetter(void) {

printf("%c", letter);

}

当我运行它时,消息“Hello!”显示为全白,就像 assembly 部件未打印 ANSI 代码一样

enter image description here

但是如果我将 c 部分更改为在每个字符后打印一个新行:

#include <stdio.h>

char letter;

void printLetter(void) {

printf("%c\n", letter);

}

然后字母显示了我在开始时预期的每种颜色之一。

enter image description here

此行为的原因可能是什么?

最佳答案

这是因为如果 stdout 进入终端,stdio(C 标准 I/O 包)对 stdout 使用行缓冲。这意味着您写入的数据不会立即发送到终端,而是会缓冲直到整行可用。您在第一个程序(一行中的 hello)中观察到的是,在您使用换行调用 printLetter 之前,实际上没有写入 Hello 的字符,从而导致 stdout 的缓冲区被冲刷到终端。

我看到以下方法可以解决您的问题(其中任何一个都可以解决问题,但只使用一种方法):

  • 编辑ansiSetRed等来调用fwrite而不是直接执行write系统调用。这应该使缓冲按预期工作。
  • 在写入任何数据之前调用 setbuf(stdout, NULL) 关闭缓冲。
  • 写入 stderr 而不是 stdout 因为 stderr 是无缓冲的
  • 在每个 printf 之后执行 fflush(stdout) 以手动刷新 stdout
  • 重写 printLetter 以使用系统调用 write 而不是 printf

关于c - 在 Linux 上混合系统调用写入和 printf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41120879/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com