如何在C项目中添加汇编代码?

问题描述 投票:0回答:2

我想编译一个简单的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   
[...]

当然我做错了。你可以帮帮我吗?

谢谢。

c assembly visual-studio-code
2个回答
1
投票

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

尝试使用编译的程序集作为起点通常更痛苦,切割和粘贴肯定但是有很多开销,并且机器生成标签,您希望清理而不是从头开始。 (我更喜欢反汇编和工作,而不是直接使用编译器输出)


0
投票

我已经复制了你的简单示例,我试图从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”,那么所有运行都可以......

我的问题在哪里?

谢谢!

© www.soinside.com 2019 - 2024. All rights reserved.