Как я могу добавить ассемблерный код в C-проекте? - PullRequest
0 голосов
/ 03 апреля 2019

Я хотел бы скомпилировать простой проект 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   
[...]

Конечно, я делаю некоторые вещи неправильно.Не могли бы вы помочь мне?

Спасибо.

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

хмм

so.c

extern "C" int fun ( void );
int x;
int main()
{
    x=fun();
    return x;
}

fun.c

int fun ( void )
{
    return(5);
}

build

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

cat fun.s

    .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 голосов
/ 08 апреля 2019

Я скопировал ваш простой пример и попытался скомпилировать его из кода Visual Studio.Когда я запускаю свои задачи "gcc build active file", я получаю эту ошибку:

/ root / C-foro / so.c: 1: 8: error: ожидаемый идентификатор или '(' beforeстроковая константа 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"
            ]
        }
    ]

, поэтому я полагаю, что моя проблемаТОЛЬКО в моем файле tasks.json в коде Visual Studio, потому что, если я запускаю в консоли "gcc fun.c -O2 -c -o fun.o", все работает нормально ...

где моя проблема?

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...