Использование C со сборкой в Windows

#c #assembly

#c #сборка

Вопрос:

Я пытаюсь скомпилировать и связать простую программу c и assembly вместе. Программа сборки должна просто вернуть значение 10 обратно в программу c, а программа c должна вывести его на экран.

У меня есть два файла 1) main.c

 #include <stdio.h>
extern int my_asm();

int main(int argc, char** argv)
{
    int r = my_asm();
    printf("Value: %in", r);

    return 0;
}
 

и 2) file.asm

 global _my_asm

    section .text
_my_asm:
    mov eax, 10
    ret
 

Сначала я компилирую программу на ассемблере следующим образом в командной строке:

 nasm -f win32 file.asm

 

В результате создается файл file.obj.

Во-вторых, я использую gcc для связывания main.c и file.obj вместе, чтобы получить мой exe-файл:

 gcc main.c file.obj -o main

 

Это создает мой main.exe файл, как и ожидалось, но когда я запускаю main.exe Я не получаю никакого результата?

Есть предложения? Спасибо.

Комментарии:

1. Вы сейчас читаете курс по Udemy из любопытства?

2. Вы получаете окно, но затем оно немедленно закрывается? Какое точное поведение вы получаете?

3. Я, конечно, есть.

4. Ха, я думаю, мы проходим тот же курс (британский чувак).

5. Ах, ха! курс для мастеров программирования на языке ассемблера x86? Вы уже зашли так далеко? Вы заставили его работать? (Ирландский американский чувак)

Ответ №1:

Эта проблема была решена.

Мне нужно было добавить флаг -m32 в команду gcc:

файл gcc main.c.obj -m32 -o main

Затем программа запустилась правильно.

Спасибо.

Комментарии:

1. Таким образом, ваш gcc по умолчанию -m64 имеет значение и не выдает ошибок, когда вы связываете nasm -fwin32 выходной файл с 64-разрядным .exe ? Это очень удивительно, у вас должен был появиться символ, для которого ошибка не найдена my_asm , потому что Win64 не использует начало _ . И что еще более важно, компоновщики должны знать, что 32- и 64-разрядный машинный код x86 не полностью совместим и отказывается их связывать. Если у вас есть версия cygwin или mingw file , вы можете file foo.exe проверить, является ли она 32-разрядной или 64-разрядной.

2. @PeterCordes Привет, Питер, спасибо за твой комментарий. Итак, я следую курсу сборки для начинающих по Udemy, и учитель связывал программы с использованием gcc без флага -m32. Все это работало для него (включая ожидаемый результат от исполняемого файла), что действительно странно? Я не получал ошибок компиляции или компоновщика (когда не использовался флаг -m32). Однако я не получал ожидаемого результата от исполняемого файла? Кстати, я на Windows 10, это как-то связано с этим?

3. Неудивительно, что это сработало для кого-то другого, если бы они установили MinGW32 вместо MinGW64, тогда gcc по умолчанию было бы -m32 . (То же самое для cygwin, если они установили 32-разрядный Cygwin). В реальной системе GNU / Linux gcc значение по умолчанию соответствует разрядности остального пользовательского пространства, но это потому, что оно устанавливается из дистрибутивных пакетов. В Windows, где вы устанавливаете GCC самостоятельно, вам решать, выбираете ли вы 32- или 64-разрядный GCC.

4. @PeterCordes Да, мы установили MinGW32. Все еще не объясняет, почему его исполняемые файлы работали, а мои — нет. Есть идеи?

5. Если ваш gcc -m32 отличается от gcc for you, то, я думаю, ваш GCC — это нечто иное, чем MingGW32 (прошло много времени с тех пор, как я действительно использовал GCC под Windows, но я знаю GCC в целом достаточно хорошо, чтобы быть уверенным. Хотя получение ошибки компоновщика не -m32 ставит под сомнение то, что она используется по -m64 умолчанию). Может быть, у вас есть еще одна установка GCC ранее в вашем PATH ? Используйте gcc -v , чтобы увидеть, для какой «цели» он был настроен. Если вы используете bash, используйте type -a gcc для просмотра всех gcc исполняемых файлов в вашем ПУТИ — первый — это то, что будет выполняться, если вы не используете явный путь.