tgo*_*eza 4 c gcc arm system-calls gem5
与此其他问题相关.我试图在gem5中运行这个简单的C程序:
int main() {
int a=1, b=2;
int c=a+b;
return c;
}
Run Code Online (Sandbox Code Playgroud)
它失败了因为gem5没有实现一些系统调用.
我的问题是,为什么像这样的简单程序需要系统调用?这应该毫无困难地运行裸机.有没有办法编译这个以避免系统调用?我正在使用arm-linux-gnueabi-gcc -static -DUNIX来编译它.
Die*_*Epp 11
没有系统调用,程序无法退出.它的工作方式通常是这样的:
// Not how it's actually implemented... just a sketch.
void _start() {
char **argv = ...;
int argc = ...;
// ... other initialization code ...
int retcode = main(argc, argv);
exit(retcode);
}
Run Code Online (Sandbox Code Playgroud)
具体细节取决于操作系统,但exit()终止该过程通常必须是系统调用或通过系统调用实现.
请注意,这适用于"托管"C实现,而不适用于"独立"C实现,并且是高度特定于操作系统的.有独立的C实现可以在裸机上运行,但托管的C实现通常需要一个操作系统.
您可以在没有标准库的情况下进行编译,也可以在没有运行时的情况下进行编译,但是您的入口点无法返回...如果没有运
通常可以编译能够运行裸金属的程序.
使用-ffreestanding.这使得GCC生成的代码不会假设标准库可用(并且具有其他效果).
使用-nostdlib.这将阻止GCC与标准库链接.需要注意的是memcmp,memset,memcpy,和memmove呼叫可能会产生无论如何,所以你可能对这些自己提供.
此时您可以编写程序,但通常必须使用_start而不是main:
void _start(void) {
while (1) { }
}
Run Code Online (Sandbox Code Playgroud)
请注意,您无法退货_start!想一想......没有地方可以回归.编译这样的程序时,您可以看到它没有使用任何系统调用,也没有加载器.
$ gcc -ffreestanding -nostdlib test.c
我们可以验证它没有加载库:
$ ldd a.out
statically linked
$ readelf -d a.out
Dynamic section at offset 0xf30 contains 8 entries:
Tag Type Name/Value
0x000000006ffffef5 (GNU_HASH) 0x278
0x0000000000000005 (STRTAB) 0x2b0
0x0000000000000006 (SYMTAB) 0x298
0x000000000000000a (STRSZ) 1 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x000000006ffffffb (FLAGS_1) Flags: PIE
0x0000000000000000 (NULL) 0x0
我们还可以看到它不包含任何进行系统调用的代码:
$ objdump -d a.out a.out: file format elf64-x86-64 Disassembly of section .text: 00000000000002c0 <_start>: 2c0: eb fe jmp 2c0 <_start>