Автор Тема: Возможно ли собрать .c, bin, .cpp и x86 ассемблерный код в один .exe?  (Прочитано 1099 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Dport

  • Пользователь
  • Сообщений: 28
    • Просмотр профиля
Всем здравствуйте, у меня вопрос такой, транслятор 68к -> x86 работает замечательно, но хотелось бы для проверки собрать прототипный экзешник. Вот, что отвечает гадалка:Да, собрать файлы с расширениями `.c`, `.cpp`и ассемблерным кодом для x86 в один `.exe` файл возможно. Разберу процесс подробно.

## Основные этапы сборки

1. **Компиляция отдельных файлов** в объектные модули (`.obj` или `.o`):
   * файлы `.c` и `.cpp` компилируются соответствующими компиляторами C/C++;
   * ассемблерный код компилируется ассемблером (например, MASM или NASM).
2. **Линковка** всех объектных файлов в единый исполняемый файл с помощью линкера.

## Инструменты для разных ОС

**Windows:**
* **Visual Studio + MASM (ml.exe)** — стандартный набор для Windows;
* **GCC (MinGW)** — если предпочитаете инструменты GNU.

**Linux:**
* **GCC + GAS (GNU Assembler)** — стандартный набор инструментов.

## Практические примеры

### Вариант 1. Использование Visual Studio (Windows)

**Шаг 1.** Создайте проект в Visual Studio.
**Шаг 2.** Добавьте файлы:
* `main.c` или `main.cpp` — основной код;
* `asm_func.asm` — ассемблерные функции.

**Шаг 3.** Настройте проект:
1. В свойствах проекта перейдите в `Build Customizations`.
2. Отметьте `masm (.targets, .props)`.
3. Убедитесь, что для `.asm` файлов установлен тип сборки `Microsoft Macro Assembler`.

**Шаг 4.** Пример кода:

*main.cpp:*
```cpp
extern "C" int asm_function(int a, int b);

int main() {
    int result = asm_function(5, 3);
    return 0;
}
```

*asm_func.asm:*
```asm
.386
.model flat, C

.code
asm_function PROC a:DWORD, b:DWORD
    mov eax, a
    add eax, b
    ret
asm_function ENDP
END
```

**Шаг 5.** Соберите проект — Visual Studio автоматически скомпилирует и свяжет все файлы.

### Вариант 2. Командная строка с GCC (MinGW для Windows или нативный GCC для Linux)

**Шаг 1.** Компиляция ассемблерного кода:
```bash
nasm -f win32 asm_func.asm -o asm_func.obj  # для Windows
# или
nasm -f elf32 asm_func.asm -o asm_func.o   # для Linux
```

**Шаг 2.** Компиляция C/C++ кода:
```bash
gcc -c main.c -o main.obj  # Windows
# или
gcc -c main.c -o main.o   # Linux
```

**Шаг 3.** Линковка всех объектных файлов:
```bash
gcc main.obj asm_func.obj -o program.exe  # Windows
# или
gcc main.o asm_func.o -o program         # Linux
```

### Вариант 3. Встроенная ассемблерная вставка

Можно вставить ассемблерный код прямо в C/C++ файл с помощью `asm` или `__asm__`:

```cpp
int add_asm(int a, int b) {
    int result;
    __asm__ (
        "addl %%ebx, %%eax;"
        : "=a" (result)
        : "a" (a), "b" (b)
    );
    return result;
}
```

## Важные нюансы

1. **Соглашения о вызовах** (calling conventions):
   * убедитесь, что ассемблерный код использует то же соглашение о вызовах, что и C/C++ код (обычно `__cdecl` или `__stdcall`);
   * в ассемблере это задаётся директивой `.model flat, C`.

2. **Имена функций**:
   * в C++ может происходить «name mangling» — используйте `extern "C"` для предотвращения;
   * для 32‑битного кода имена функций могут иметь ведущий подчёркивание (`_function`).

3. **Архитектура**:
   * убедитесь, что все файлы компилируются для одной архитектуры (x86 32‑bit);
   * 64‑битная сборка имеет ограничения на встроенную ассемблерную вставку.

4. **Инструменты**:
   * MASM (ml.exe) — для Windows, совместим с Visual Studio;
   * NASM — кроссплатформенный, требует указания формата вывода;
   * GAS — используется с GCC, синтаксис отличается от MASM.

---

## Краткий итог

**Да, собрать можно. Для этого:**
1. Компилируйте каждый файл в объектный модуль своим инструментом.
2. Свяжите все объектные файлы в один исполняемый с помощью линкера.
3. Следите за согласованностью соглашений о вызовах и имён функций.

Наиболее удобный способ для Windows — Visual Studio с MASM, для кроссплатформенной разработки — GCC + NASM.

Хотите, я раскрою какой‑то из этапов подробнее или помогу с конкретным примером для вашей среды разработки?
Хотелось бы и .bin файлы туда включить(графика в сониках только в таком формате, наверное, и в других Мегадрайвовских играх также).
« Последнее редактирование: 16 Мая 2026, 23:57:06 от Dport »

Оффлайн wolfer

  • Пользователь
  • Сообщений: 3193
  • Пол: Мужской
  • Mens sana in corpore sano
    • Просмотр профиля
Ну если Вы c/cpp скомпилите тоже в x86, то почему бы и нет.

Оффлайн Беларус

  • Модератор
  • Сообщений: 1549
    • ВКонтакте
    • Steam
    • Просмотр профиля
Вопрос в том, можно ли верить ИИ или што?
Ты пробовал ему давать полученный асм-код, штобы он показал аналогичный вариант на С/С++? Зачем тебе продолжать возитса с асэмблерами далее?

Оффлайн Dport

  • Пользователь
  • Сообщений: 28
    • Просмотр профиля
Я тут в теме про рекомпил прочитал, что практичнее реасм под другую платформу. 

Добавлено позже:
Ну если Вы c/cpp скомпилите тоже в x86, то почему бы и нет.
А с .bin файлами(сжатая графика) как быть? Как-то можно их туда включить?

Добавлено позже:
Мне говорили, что в с/с++ файлах можно использовать inline assembly т.е. вызывать асм в с/с++ коде. Но мне надо почитать подробнее про это.

Оффлайн Беларус

  • Модератор
  • Сообщений: 1549
    • ВКонтакте
    • Steam
    • Просмотр профиля
Можно, а ещё в Си давно есть включение бинарника (#embed), скоро и С++ подтянетса.

Оффлайн SegaMark

  • Пользователь
  • Сообщений: 150
  • Пол: Мужской
    • Просмотр профиля
откуда у тебя взялся одновременно C и C++ код?
как по мне проще всего выбрать что то одно C/C++ и использовать ассемблерные вставки.

Если bin у тебя графика, то тебе надо сначала решить, через что ты ее будешь рендерить, и от этого уже отталкиваться.
Потом открываешь в C bin-файл через функции чтения файла и конвертируешь, чтобы он выводился через твой механизм рендера, если хочешь через asm, то это сложнее, но принцип такой же.

Оффлайн Dport

  • Пользователь
  • Сообщений: 28
    • Просмотр профиля
Sonic & Knuckles Collection (официальный порт на пк от Сеги) использовал c++ оболочку для мультимедийных операций, в С же у меня портированный код, отвечающий за vdp(в самом порте он был на чистом x86 асме, но чел, занимающийся С портом - декомпиляцией перевел его в С)

Оффлайн SegaMark

  • Пользователь
  • Сообщений: 150
  • Пол: Мужской
    • Просмотр профиля
в С же у меня портированный код, отвечающий за vdp
Через что он рендерит то? Неужели на прямую через winAPI выводит?

Добавлено позже:
мультимедийных операций
Что имеется ввиду под мультимедийными операциями?
« Последнее редактирование: 17 Мая 2026, 17:16:35 от SegaMark »

Оффлайн Dport

  • Пользователь
  • Сообщений: 28
    • Просмотр профиля
SegaMark, Звук, мегадрайвовская графика.

Добавлено позже:
Через что он рендерит то? Неужели на прямую через winAPI выводит?
Спрошу у автора С порта, позже напишу
« Последнее редактирование: 17 Мая 2026, 17:44:08 от Dport »

Оффлайн SegaMark

  • Пользователь
  • Сообщений: 150
  • Пол: Мужской
    • Просмотр профиля
Звук, мегадрайвовская графика.

Я тогда вообще не понял разницу
c++ оболочку для мультимедийных операций, в С же у меня портированный код, отвечающий за vdp
VDP тоже отвечает за вывод графики.

Добавлено позже:
Мне все равно кажется что ты перемудрил и нужно к чему то одному прийти C/C++/ASM.
Или проще это на модули разбить и для каждого модуля dll сделать, плюс общий exe добавить, которая будет дёргать из dll функции.
Без конкретного кода сложно сказать что у тебя сейчас там за проект получился.

Оффлайн SeregaZ

  • Пользователь
  • Сообщений: 2958
  • Пол: Мужской
  • ливнул с форума
    • Youtube
    • Просмотр профиля
да эмулятор вам нужен :) эмулятор это и есть по сути перевод сеговского кода в виндовый.

Оффлайн wolfer

  • Пользователь
  • Сообщений: 3193
  • Пол: Мужской
  • Mens sana in corpore sano
    • Просмотр профиля
Нет никакой проблемы в одном проекте совместить С и С++ файлы исходного кода. И асм скомпилить предварительно и все слинковать. Было бы желание :) А куда там ресурсы всякие пришивать и как с ними работать - это задача творческая. Можно из файла считать, можно в винхексе в байтовый массив перевести и переменной в проект добавить…

Оффлайн Dport

  • Пользователь
  • Сообщений: 28
    • Просмотр профиля
да эмулятор вам нужен :) эмулятор это и есть по сути перевод сеговского кода в виндовый.
Ну, не совсем, для наглядности своей идеи прикрепляю сам Sonic & Knuckles Collection 97-го года(как вы понимаете, эмуляторов тогда еще не было, (s3k.ini надо положить в папку windows, иначе слишком быстро идти будет) запускаем саму игру через SONIC3K.EXE. Хотелось бы также, но с любой другой сеговской игрой(только дизасм нужен для конвертации в x86 asm). Это яркий пример реасма под целевую платформу. Игра идентична оригиналу.
« Последнее редактирование: 17 Мая 2026, 21:29:22 от Dport »

Оффлайн SegaMark

  • Пользователь
  • Сообщений: 150
  • Пол: Мужской
    • Просмотр профиля
да эмулятор вам нужен  эмулятор это и есть по сути перевод сеговского кода в виндовый.
В эмуляторе ты должен сэмулировать все части железа(VDP, RAM, CRAM, Z80...), а в винде у тебя по сути проц, оперативка и API для вывода на экран

Добавлено позже:
прикрепляю сам Sonic & Knuckles Collection 97-го года
А где код на C/C++/ASM?

Оффлайн Dport

  • Пользователь
  • Сообщений: 28
    • Просмотр профиля
В самом роме исходников нет, ясно дело, кто их станет класть в продаваемые диски, но есть в декомпиляции, прикрепляю архив. Ответ от автора насчет С/С++ кода: All of the .cpp files make up most of the wrapper. graphics.cpp sends the framebuffer to DirectX, while csound.cpp is responsible for sound effects.

The graphics are stored in Mega Drive format inside the executable. The game writes to a memory region that it considers the VDP's. The code for reading from that region and blitting to the framebuffer seems to be written in x86 assembly, but I converted it to C (vdp.c).

The code for handling vertical interrupts is in main.cpp, one of which gets called each frame and reads controller input, uploads the current palette, converts the sprite format, etc.
P.S. а асм легко можно посмотреть через ghidra или бесплатную версию ida, они из-под коробки работают с .exe файлами.
« Последнее редактирование: 18 Мая 2026, 11:22:15 от Dport »

Оффлайн SegaMark

  • Пользователь
  • Сообщений: 150
  • Пол: Мужской
    • Просмотр профиля
Dport, Так какая у тебя конечная цель?

Оффлайн Dport

  • Пользователь
  • Сообщений: 28
    • Просмотр профиля
SegaMark, Первого соника (хотя бы) портировать на пк, а дальше как пойдет.

Оффлайн Беларус

  • Модератор
  • Сообщений: 1549
    • ВКонтакте
    • Steam
    • Просмотр профиля
А если попробовать потихоньку переписать ево дизасм нейросетями на Си/С++?

Оффлайн Werton

  • Пользователь
  • Сообщений: 1068
  • Пол: Мужской
    • Youtube
    • Просмотр профиля
SegaMark, Первого соника (хотя бы) портировать на пк, а дальше как пойдет.
В дискорде MD Engine тоже один чел одержим этой навязчивой идеей, спрашивает сможет ли этот MD Engine импортировать и скомпилировать дизасм первого соника, сейчас или в потом. Но все увещевания, что это asm68k дизасм, а не gcc пролетают мимо него. Это не ты случайно?  :)

Оффлайн SegaMark

  • Пользователь
  • Сообщений: 150
  • Пол: Мужской
    • Просмотр профиля
А если попробовать потихоньку переписать ево дизасм нейросетями на Си/С++?
Там все равно главная проблема будет это вывод на экран. Думаю с этого надо начинать

Оффлайн Беларус

  • Модератор
  • Сообщений: 1549
    • ВКонтакте
    • Steam
    • Просмотр профиля
Я поэтому и предложыл ИИ, потому што это не тупо конвертирование одново кода в другой. ИИ про графику Сеги должен знать всё, и про SDL2.

Оффлайн Dport

  • Пользователь
  • Сообщений: 28
    • Просмотр профиля
В дискорде MD Engine тоже один чел одержим этой навязчивой идеей, спрашивает сможет ли этот MD Engine импортировать и скомпилировать дизасм первого соника, сейчас или в потом. Но все увещевания, что это asm68k дизасм, а не gcc пролетают мимо него. Это не ты случайно?  :)
У меня нет дискорда.  :biggrin: