rudy-peto Ответов: 3

Как Преобразовать Код C++ В Ассемблер, Чтобы Я Мог Скомпилировать Его С Помощью Emu8086?


#include<stdio.h>

int main(){
	printf("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}

я попытался скомпилировать приведенный выше код C++ под windows с помощью g++ -S test1.cpp -o test1.o чтобы получить сборку. но это не было похоже на сборку, которую я использовал в emu8086. это выглядело так:
	.file	"test1.cpp"
	.def	___main;	.scl	2;	.type	32;	.endef
	.section .rdata,"dr"
LC0:
	.ascii "ABCDEFGHIJKLMNOPQRSTUVWXYZ\0"
	.text
	.globl	_main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
LFB7:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	andl	$-16, %esp
	subl	$16, %esp
	call	___main
	movl	$LC0, (%esp)
	call	_printf
	movl	$0, %eax
	leave
...................................blablablabla


I used to write assembly in emu8086 like this:

ORG 100H
TDATA: JMP PROCESS
        KAL DB 'TEXTTEXTTEXTTEXT',10,13,'$'
PROCESS: MOV CX,11H
        XOR BX,BX
        LEA DX,KAL
PRINT: MOV AH,09H
       INT 21H 
       INC BX
       CMP BX,CX
       LOOP PRINT
       INT 20H
END TDATA     


любая идея будет оценена по достоинству.
Спасибо
--Руди

3 Ответов

Рейтинг:
4

Frankie-C

Если вы действительно хотите использовать компилятор для создания списка ассемблеров для повторного использования в вашем коде, вы должны понимать, что вам нужен компилятор DOS C, а не 32/64-битный компилятор, такой как GCC.
Если вы действительно хотите, продолжайте скачивать бесплатную версию TURBOC 2.01, которая широко доступна по всему миру. Ты найдешь его здесь[^], или здесь[^], или здесь[^]...
Для C++ Вы можете скачать TurboC++ 1.00 или TurboC++ 3.00 с сайта здесь[^].
Вы также можете использовать производную Delorie (DJGPP) , цифровой Mars или старую версию Watcom (просто google вокруг)...


Рейтинг:
1

Frankie-C

EMU8086-это эмулятор, ассемблер и т. д. Только для 16-битного кода 8086. Он эмулирует старую 16-битную DOS-ОС. В частности, код, который вы использовали, начиная с исходной метаинструкции, обозначает запись двоичного исполняемого файла '.com' (по умолчанию расположенного по адресу adrress 0x100). Для вывода символов используются вызовы прерываний DOS (INT 21H).
Фактические ОС имеют 32/64 бита, они используют другую компоновку памяти и обычно расположены на 0x40000, но могут быть реорганизованы компоновщиком. В реальном коде программа будет нормально запускаться из библиотеки времени выполнения (т. е. MSVCrt.lib/MSVCrt.dll), которые затем вызывают вашу точку входа (main, wmain, WinMain и т. д. В зависимости от подсистемы, выбранной в компоновщике). В реальных программах 'printf- это библиотечная функция, а не вызов DOS, поэтому компилятор генерирует код для ее вызова.
В современных ОС существует стандартная последовательность инструкций для сохранения фактического указателя стека и выделения места для локальных переменных (поверх стека), называемых 'preamble- Преамбула-это то, что кажется вам таким странным...
Почему я все так усложнил? Потому что в наши дни это немного сложнее, чем в старые дни DOS :(.
Ассемблер, который вы получили от gcc, предназначен для 32-битного PE-исполняемого файла, а не для 8086 16-битного старого DOS :).
Кроме того, ваша сборка (поддерживаемая MS MASM) является синтаксисом INTEL, в то время как GCC использует синтаксис сборки AT&T, который является форматом deafult GAS (GNU ASsembler). Видеть здесь[^] для синтаксиса AT&T.
Смотри здесь[^], вы найдете множество учебных пособий. Сразу после прочтения первого вы на удивление лучше поймете ассемблер, который вы получили от GCC ;).

П. С. Попробуйте добавить '-masm=intel- для вас командная строка g++ должна выдавать ассемблер в синтаксисе INTEL.


Рейтинг:
0

OriginalGriff

Это потому, что это вывод компилятора - и он не знает, что означает код! Поэтому он использует свой "универсальный" механизм передачи параметров - через стек - для передачи строки const функции, которая может выполнять печать, вместо того чтобы "знать", что вы пытаетесь сделать, и просто создавать код для этого.

Честно говоря, вывод компилятора-это не очень хорошее начало для любого проекта сборки, он никогда не будет так хорош, как компетентный ручной кодер. Я бы вообще не стал использовать его для изучения материала! :смеяться:


rudy-peto

Значит, дело в том, что я должен кодировать его вручную? Другого выхода нет?

В Любом Случае, Спасибо
--Руди

OriginalGriff

Я бы сказал - вы не получите "хороший код" от компилятора!

Frankie-C

Хотя это не реальный вариант использовать компилятор для генерации ассемблера для повторного использования дело в том, что вам нужен компилятор DOS, который вы не можете использовать GCC!
Смотрите мое другое решение...