- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一段 C 代码调用了一个在汇编中定义的函数。举例来说,假设 foo.c 包含:
int bar(int x); /* returns 2x */
int main(int argc, char *argv[]) { return bar(7); }
并且 bar.s 包含 bar() 在 x86 汇编中的实现:
.global bar
bar: movl 4(%esp), %eax
addl %eax, %eax
ret
在 Linux 上,我可以使用 GCC 轻松编译和链接这些源代码,如下所示:
% gcc -o test foo.c bar.s
% ./test; echo $?
14
在带有 MinGW 的 Windows 上,此操作失败并出现错误“对 ‘bar’ 的 undefined reference ”。事实证明,这是因为在 Windows 上,所有具有 C 调用约定的函数标识符都带有下划线前缀,但由于“bar”是在程序集中定义的,因此它没有获得此前缀,因此链接失败。 (所以错误消息实际上是在提示缺少符号 _bar,而不是 bar。)
总结:
% gcc -c foo.c bar.s
% nm foo.o bar.o
foo.o:
00000000 b .bss
00000000 d .data
00000000 t .text
U ___main
U _bar
00000000 T _main
bar.o:
00000000 b .bss
00000000 d .data
00000000 t .text
00000000 T bar
现在的问题是:我怎样才能很好地解决这个问题?如果我只为 Windows 编写,我可以将下划线添加到 bar.s 中的标识符,但随后代码在 Linux 上中断。我查看了 gcc 的 -fleading-underscore
和 -fno-leading-underscore
选项,但似乎都没有执行任何操作(至少在 Windows 上)。
我现在看到的唯一替代方法是将程序集文件传递给 C 预处理器,如果定义了 WIN32,则手动重新定义所有声明的符号,但这也不是很好。
有没有人对此有一个干净的解决方案?也许是我监督的编译器选项?也许 GNU 汇编程序支持一种方法来指定这个特定符号是指使用 C 调用约定的函数并且应该被这样处理?还有其他想法吗?
最佳答案
虽然危险,但一种选择是说服 GCC 省略 ABI 要求的前导下划线。
This option and its counterpart,
-fno-leading-underscore
, forcibly change the way C symbols are represented in the object file. One use is to help link with legacy assembly code.Warning: the
-fleading-underscore
switch causes GCC to generate code that is not binary compatible with code generated without that switch. Use it to conform to a non-default application binary interface. Not all targets provide complete support for this switch.
另一个更安全的选择是明确告诉 GCC 要使用的名称。
5.39 Controlling Names Used in Assembler Code
You can specify the name to be used in the assembler code for a C function or variable by writing the
asm
(or__asm__
) keyword after the declarator as follows:int foo asm ("myfoo") = 2;
This specifies that the name to be used for the variable
foo
in the assembler code should be ``myfoo' rather than the usual \``_foo
'.On systems where an underscore is normally prepended to the name of a C function or variable, this feature allows you to define names for the linker that do not start with an underscore.
It does not make sense to use this feature with a non-static local variable since such variables do not have assembler names. If you are trying to put the variable in a particular register, see Explicit Reg Vars. GCC presently accepts such code with a warning, but will probably be changed to issue an error, rather than a warning, in the future.
You cannot use
asm
in this way in a function definition; but you can get the same effect by writing a declaration for the function before its definition and puttingasm
there, like this:extern func () asm ("FUNC");
func (x, y)
int x, y;
/* ... */It is up to you to make sure that the assembler names you choose do not conflict with any other assembler symbols. Also, you must not use a register name; that would produce completely invalid assembler code. GCC does not as yet have the ability to store static variables in registers. Perhaps that will be added.
在你的情况下,
extern int bar(int x) asm("bar");
应该告诉 GCC“bar
使用 asm 名称 ``bar`',即使它是一个 ccall 函数”。
关于c - 在 Win32 上使用 GCC 向程序集符号添加前导下划线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1034852/
我目前有以下选择语句: SELECT CONCAT(TRUNCATE(HOUR("215:00:36")/24,0),":",HOUR("215:00:36")%24,":",MINUTE("215:
我正在尝试将字符串编码为 base36。 static char *decode(unsigned long long value) { char base36[37] = "01234567
如果我有一个输入字符串,input 有三个或更多小数位,我希望该字符串由单独的 if-loop 处理。 我为此目的创建了以下控制台程序,如果(第一个约束)有小数点 .,则输入 if-loop字符串和(
我有一小段代码,它有一个整数数组,其中包含一些前导 0 的元素。 int arr[]={012,234,071}; cout<
如何从强制范围中删除前导,以便 Some field Any 1 2 3 « 最佳答案 删除 vertical-align: middle 后我觉得不错。 .mandato
我有这个 psd 并试图将它转换为 html css。 但是我无法从psd中计算出css中的行高。 如何根据前导+字体大小计算行高? 谢谢 最佳答案 如果行距不是自动的:LineHeight = fo
有谁知道如何更改文本字段上的行高(行距),最好是在 Interface Builder 中? 我已经找了大约一个小时了,但没有找到。 最佳答案 解决方法如下: Resizing NSTextField
是否可以在 C# 中的单元格元素(行)之间添加空格?我正在 Visual Studio 2012 中创建 pdf,并希望在行之间设置一些空间。我有这样的东西: PdfPTable cellTable
是否可以在 C# 中的单元格(行)元素之间添加空格?我正在 visual studio 2012 中创建一个 pdf,并希望在行之间设置一些空间。我有这样的东西: PdfPTable cellTabl
type ApplyFunc func(commitIndex uint64, cmd []byte) []byte 对于这个声明。我的理解是,这是一个函数指针。它的名字是 ApplyFunc。并且此
我很好奇多列索引的前导列的概念。 我正在使用这个示例 dvdrental分贝。 这是查询: SELECT title, length, rating, replacement_cost
我想将一个 double 格式格式化为最大长度为7的字符串,其中包含一个点“.”以及其后一位数字。 例如: 123.4 becomes "00123.4" 12345 becomes "12345
我需要正则表达式的帮助来从字符串中去除不需要的字符(在 Java 中)。我用 4 个正则表达式解决了这个问题。替换将被多次调用 [peeks: 50+ times/sec] 它并降低性能。但我认为它肯
只是将两个值连接到 mysql 表中的一列。 mysql 表中的第一个值和 PHP 常量中的第二个值保存为 define('ACCOUNTCODESUFFIX','016');。 MySql 查询有点
我如何按此顺序返回这些: 1: aaaa 2: bbbb 3: the cccc 4: dddd 所以忽略开头的“the” 目前我正在使用。 select * from houses order by
我通常使用以下代码将 PHP 变量导入 JavaScript: echo("var zipCode = " . $zipCode . ";"); 这工作正常,但对于以 0 开头的邮政编码,它会被 ch
有什么方法可以用前导 0 和小数来格式化 NSNumber 吗?例如,我需要有能力写 4.5 和 000。目前我有它允许小数,但不允许前导 0。 NSNumberFormatter *f = [[NS
你好我正在以编程方式创建标签栏,在我的功能中需要选择填充自定义颜色的标签,到目前为止我已经使用下面的代码实现了这一点,下面的输出见截图。 tabBarController.tabBar.selecti
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Integer with leading zeroes 有人能告诉我这是怎么回事吗?当我用前导零初始化一个
在 Xcode 6 中,我可以使用编辑器菜单来固定: 引领空间至超视 到 Superview 的尾随空间 顶部空间到Superview Superview的底部空间 我找不到在 Xcode 7 bet
我是一名优秀的程序员,十分优秀!