0

我面临着在不使用任何库的情况下打印(在控制台中)一个值的问题。我试图通过 main 函数的返回值来做到这一点,但似乎没有办法在不使用 printf() 的情况下在控制台中显示函数的返回值。我正在寻找一条建议,所以请随意“集思广益”。欢迎任何想法,希望你能帮助我,并在手前谢谢你。

4

2 回答 2

2

从技术上讲,write(注意write而不是fwrite)不是库函数,而是系统调用。stdout(这是将出现在屏幕上的内容),如果您能够STDOUT_FILENO使用write.

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

于 2021-06-09T02:46:30.877 回答
2

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

“从技术上讲”,您需要了解您的 ABI,并且您需要知道如何在编译器中调用该 ABI。然后,您需要(通常,对于大多数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 可能被认为是标准库。这取决于。有时它也是一个链接器脚本。这当然是您的编译器工具链为您提供的东西。我不打算在这里复制它,但对于您感兴趣的任何平台,谷歌“最小二进制”或类似的东西。很多人为他们的“频道”做过这种事情......

于 2021-06-09T04:22:47.637 回答