我在理解除 C 之外的编程语言的标准库是如何编写的有问题。
据我了解,C 标准库可以在 C 和汇编程序的混合中实现,其中需要汇编程序以便可以调用系统调用,因此可以使用 fopen、fscanf ...。
其他编程语言如何使用它们的标准库来完成这个功能(使用 i/o、文件、所有其他需要系统调用的东西)?它们是否都允许像 C 这样的汇编器内联,还是有其他方法?
我已经读过可以使用 C 及其标准库来实现其他语言库,但我不确定这是如何完成的。
编辑1. 试图更具体。
(实现标准库的语言称为new_lang。)
如果有人可以详细说明如何在对象代码级别和实现级别完成第二种方法(使用 C 运行时),因为我无法理解的是:
我试图尽可能笼统,但我不知道如何在不详细说明的情况下解释这个问题。
我在下面编写了简单的C程序(test.c): -
#include<stdio.h>
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并执行以下内容以了解.bss段中的大小更改.
gcc test.c -o test
size test
Run Code Online (Sandbox Code Playgroud)
输出结果如下: -
text data bss dec hex filename
1115 552 8 1675 68b test
Run Code Online (Sandbox Code Playgroud)
我没有声明全局或静态范围.所以请解释为什么bss段大小为8个字节.
我做了以下改变: -
#include<stdio.h>
int x; //declared global variable
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但令我惊讶的是,输出与以前相同: -
text data bss dec hex filename
1115 552 8 1675 68b test
Run Code Online (Sandbox Code Playgroud)
请解释.然后我初始化了全球: -
#include<stdio.h>
int x=67; //initialized global variable
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
数据段大小按预期增加,但我没想到bss段的大小会减少到4(相反,当没有声明任何内容时为8).请解释.
text data bss dec hex filename …Run Code Online (Sandbox Code Playgroud) 我看到我认为Microsoft Visual Studio 2003工具输出的目标文件的奇怪行为.该file实用程序告诉我:
asmfile.obj: 80386 COFF executable not stripped - version 30821
Run Code Online (Sandbox Code Playgroud)
对于汇编程序创建的对象,但对于来自C文件的对象,我只得到:
cfile.obj: data
Run Code Online (Sandbox Code Playgroud)
使用Microsoft的dumpbin实用程序和objdump我从cygwin获得的,我可以反汇编程序集生成的文件,但是我从C-built文件的任一实用程序中都得不到有用的结果.
我有几个与这种差异有关的问题:
我对使用AT&T语法进行反汇编特别感兴趣 - 我正在做一个大型源代码库的端口以使其与GCC一起工作,我想使用此方法作为一些内联汇编例程的快捷方式.项目.
编辑:添加更多信息.
当我dumpbin在其中一个文件上运行时,没有给出任何结果:
C:\> dumpbin /disasm Func.obj
Microsoft (R) COFF/PE Dumper Version 7.10.6030
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file Func.obj
FileType: ANONYMOUS OBJECT
Run Code Online (Sandbox Code Playgroud)
有objdump,它给出:
$ objdump -d Func.obj
objdump: Func.obj: File truncated
Run Code Online (Sandbox Code Playgroud)
关于从汇编构建的文件,我得到了合理的结果.
再次编辑:添加命令行信息.
汇编文件使用类似于以下内容的命令行构建:
ml -nologo -W3 -WX -c -coff -FoAssemblyFile.obj -Zi -Cx …Run Code Online (Sandbox Code Playgroud) 我是delphi的新手.我试图在我的Delphi项目中添加C Object文件并直接链接它们,因为Delphi支持C Object Linking.当我链接单个Object文件时,我得到了它.但是当我尝试链接多个目标文件时,我收到错误"不满意的前向或外部声明".我在Delphi 2007以及XE中尝试过这个.所以我在这里做错了什么?
工作守则:
function a_function():Integer;cdecl;
implementation
{$Link 'a.obj'}
function a_function():Integer;cdecl;external;
end.
Run Code Online (Sandbox Code Playgroud)
错误代码:
function a_function():Integer;cdecl;
function b_function();Integer;cdecl;
function c_function();Integer;cdecl;
implementation
{$LINK 'a.obj'}
{$LINK 'b.obj'}
{$LINK 'c.obj'}
function a_function():Integer;cdecl;external;
function b_function();Integer;cdecl;external;
function c_function();Integer;cdecl;external;
end.
Run Code Online (Sandbox Code Playgroud) 我试着理解mmo目标文件格式是如何工作的,这用于Don Knuth的教育MMIX架构.我没有买过MMIXware,所以我必须从汇编程序和模拟器的文字源文件中猜出大部分细节.
对象格式使用特殊的三元搜索trie来存储符号表.看看代码,我不太明白它是如何工作的.有人可以向我解释一些细节吗?特别是关于如何序列化树.
我正在使用gcc编译器和ubuntu 12.04操作系统.我想知道在哪里可以找到目标文件以及在哪个目录下,其中包含printf函数的定义.我不是在寻找包含原型的头文件,而是包含实际定义的目标文件.
我想重写目标文件,以便将大多数函数的地址更改为无操作函数。我怎样才能做到这一点?
更多上下文:在 C++ 中,我想默认自动模拟所有函数。从打电话a()和a() {}打电话b()到b() {}真正a()打电话replacement() {}和b()也打电话(相同)replacement() {}。
到目前为止我考虑过的事情:
objcopy --redefine-syms=filename- 这改变了符号的名称,而不是它的地址。--wrap参数 - 这需要__wrap_NameOfWrappedThing为我想要包装的每个东西编译一个不同的符号,并且通常看起来它不能很好地缩放。当引用目标文件/可执行文件时,我对“段”和“节”之间是否存在差异感到困惑。
根据https://en.wikipedia.org/wiki/Object_file:
大多数目标文件格式被构造为单独的数据部分,每个部分包含某种类型的数据。
不过,本文稍后会继续讨论段(例如代码段、数据段等)。
此外,PE 文件格式(Windows 中的 .exe/.dll/.coff)将这些不同部分称为节(https://msdn.microsoft.com/en-us/library/windows/desktop/ms680547(v= vs.85).aspx )。
所以我的问题是:两者之间有区别还是实际上是同义词?
我想以编程方式修改 C++ 函数或变量的名称 - 以获取将出现在编译的目标文件中的符号名称。我正在使用 Linux 和 GCC。
现在,为什么这不是一件小事呢?例如typeid(foo).name()?因为这不符合您的要求:考虑以下程序:
#include <iostream>
extern int foo(int x) { return 0; }
extern double bar(int x) { return 1.0; }
int main()
{
std::cout << typeid(foo).name() << std::endl;
std::cout << typeid(bar).name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
让我们看看这给了我们什么:
$ g++ -o a.o -O0 -c a.cpp
$ objdump -t a.o | egrep "(bar|foo)"
00000000000000dd l F .text 0000000000000015 _GLOBAL__sub_I__Z3fooi
0000000000000000 g F .text 000000000000000e _Z3fooi
000000000000000e g F .text 000000000000001b _Z3bari
$ ./a
FiiE
FiiE …Run Code Online (Sandbox Code Playgroud) object-files ×10
c ×4
c++ ×2
gcc ×2
linker ×2
abi ×1
coff ×1
delphi ×1
delphi-2007 ×1
delphi-xe ×1
disassembly ×1
exe ×1
executable ×1
ld ×1
linux ×1
mmix ×1
objdump ×1
printf ×1
size ×1
trie ×1
visual-c++ ×1