打印一个值到控制台避免使用标准库

Printing a value to console avoiding the usage of standard libraries

我遇到了在不使用任何库的情况下打印(在控制台中)值的问题。我试图通过 main 函数的 returning 值来做到这一点,但似乎没有办法在不使用 printf() 的情况下在控制台中显示函数的 return 值。我正在寻找一条建议,请随时 'brainstorm'。欢迎任何想法,希望你能帮助我,先谢谢你。

从技术上讲,write(注意 write 而不是 fwrite)不是库函数,而是系统调用。 stdout(即将出现在屏幕上的内容),如果您能够使用 write 找到它的文件描述符编号(提示提示,STDOUT_FILENO),则可以将其写入。

希望对您有所帮助!如果您需要更多指导,请随时发表评论!

好吧,当你说 write() 时你所说的“技术上”在标准库中仍然是“技术上”的(尽管它可能是 .h 文件中的一些宏魔术,具体取决于你的编译器)。有调用每个系统调用的存根函数。

“从技术上讲”,您需要了解您的 ABI,并且您需要知道如何在您的编译器中调用该 ABI。然后您需要(通常,对于 most ABI)当前写入的系统调用号是什么等等。

查找 linux(这不是我的家乡星球,但它有可能是你的星球)SYS_WRITE 是 linux 上的系统调用 #1。你把它放在 %rax 中,fd 放在 %rdi 中,缓冲区指针放在 %rsi 中,字符数放在 %rdx 中。

我们开始吧:

mov edx,4       ; message length
mov ecx,msg     ; message to write
mov ebx,1       ; file descriptor (stdout)
mov eax,4       ; system call number (sys_write)
int 0x80        ; call kernel

那些在家阅读的人可能记得您的 BIOS 曾说过一些关于 INT 80 的内容。同样是 INT 80。

现在您只需要将该程序集放入您的 C 文件中。看起来你使用 gcc asm

所以...

main()
{
__asm__("mov    edx,4       ; message length"
        "mov    ecx,msg     ; message to write"
        "mov    ebx,1       ; file descriptor (stdout)"
        "mov    eax,4       ; system call number (sys_write)"
        "int    0x80        ; call kernel");
}

现在...我不是在这里告诉您如何将 C 字符串放入寄存器,而是再次强调“技术上”...

注意:另请注意,我从此处复制了两个不同的示例以显示一些代码来说明我的观点。 X86 上的寄存器名称一团糟,我认为该段落使用的命名约定与代码片段不同。

NB2:更迂腐地说,“技术上”crt.o 可能被认为是标准库。这取决于。有时它也是一个链接描述文件。这肯定是您的编译器工具链为您提供的东西。我不打算在这里复制它,但是对于您感兴趣的任何平台,google“最小二进制”或类似的东西。很多人都为他们的“频道”做过这种事...