我想编译一个简单的C项目,它有一些在ASM文件中定义的外部函数。我的主文件是一个C ++,它调用一些在程序集文件中定义的“extern”C“”函数。
当我运行任务“g ++ build active file”时,我收到一些关于“extern”的警告以及关于asm文件中定义的函数的一些错误,告诉“未定义my_funcions的引用”。
我的C ++文件包含这样的“extern”:
[...]
extern "C" {
// Subrutines en ASM
void posCurScreenP1();
void moveCursorP1();
void openP1();
void getMoveP1();
void movContinuoP1();
void openContinuousP1();
void printChar_C(char c);
int clearscreen_C();
int printMenu_C();
int gotoxy_C(int row_num, int col_num);
char getch_C();
int printBoard_C(int tries);
void continue_C();
}
[...]
我的asm文件包含这个:
.586
.MODEL FLAT, C
; Funcions definides en C
printChar_C PROTO C, value:SDWORD
printInt_C PROTO C, value:SDWORD
clearscreen_C PROTO C
clearArea_C PROTO C, value:SDWORD, value1: SDWORD
printMenu_C PROTO C
gotoxy_C PROTO C, value:SDWORD, value1: SDWORD
getch_C PROTO C
printBoard_C PROTO C, value: DWORD
initialPosition_C PROTO C
.code
[...]
当然我做错了。你可以帮帮我吗?
谢谢。
嗯
so.c
extern "C" int fun ( void );
int x;
int main()
{
x=fun();
return x;
}
fun.c
int fun ( void )
{
return(5);
}
建立
gcc fun.c -O2 -c -o fun.o
g++ -O2 so.cpp fun.o -o so
没有错误
00000000004003e0 <main>:
4003e0: 48 83 ec 08 sub $0x8,%rsp
4003e4: e8 17 01 00 00 callq 400500 <fun>
4003e9: 89 05 45 0c 20 00 mov %eax,0x200c45(%rip) # 601034 <x>
4003ef: 48 83 c4 08 add $0x8,%rsp
4003f3: c3 retq
0000000000400500 <fun>:
400500: b8 05 00 00 00 mov $0x5,%eax
400505: c3 retq
可以,然后呢
morefun.s
.globl fun
fun:
mov $0x5,%eax
retq
建立
as morefun.s -o morefun.o
g++ -O2 so.cpp morefun.o -o so
没有错误,
检查
00000000004003e0 <main>:
4003e0: 48 83 ec 08 sub $0x8,%rsp
4003e4: e8 0d 01 00 00 callq 4004f6 <fun>
4003e9: 89 05 45 0c 20 00 mov %eax,0x200c45(%rip) # 601034 <x>
4003ef: 48 83 c4 08 add $0x8,%rsp
4003f3: c3 retq
0000000004004f6 <fun>:
4004f6: b8 05 00 00 00 mov $0x5,%eax
4004fb: c3 retq
仍然看起来不错,通过使它看起来像C函数将组件添加到C ++项目没问题。
其他路径
int fun ( void )
{
return(5);
}
gnu和大多数其他理智编译器编译为asm然后调用汇编程序,这样你就可以看到他们是如何做到的并重复
gcc -O2 -S fun.c -o fun.s
as fun.s -o fun.o
猫咪
.file "fun.c"
.section .text.unlikely,"ax",@progbits
.LCOLDB0:
.text
.LHOTB0:
.p2align 4,,15
.globl fun
.type fun, @function
fun:
.LFB0:
.cfi_startproc
movl $5, %eax
ret
.cfi_endproc
.LFE0:
.size fun, .-fun
.section .text.unlikely
.LCOLDE0:
.text
.LHOTE0:
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
或使用save-temps。
gcc -O2 -c -save-temps fun.c -o fun.o
查看编译器生成的asm
尝试使用编译的程序集作为起点通常更痛苦,切割和粘贴肯定但是有很多开销,并且机器生成标签,您希望清理而不是从头开始。 (我更喜欢反汇编和工作,而不是直接使用编译器输出)
我已经复制了你的简单示例,我试图从Visual Studio Code编译它。当我运行“gcc build active file”任务时,我收到此错误:
/root/C-foro/so.c:1:8:错误:期望的标识符或'('在字符串常量extern之前“C”int fun(void);
我的gcc构建任务在Visual Studio代码中以这种方式配置:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-O2",
"-c",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "/usr/bin"
},
"problemMatcher": [
"$gcc"
]
}
]
所以我想我的问题只出现在Visual Studio Code中的tasks.json文件中,因为如果我在控制台中运行“gcc fun.c -O2 -c -o fun.o”,那么所有运行都可以......
我的问题在哪里?
谢谢!