-Jak wygląda kompatybilność między systemami?
Moim zdaniem, jeśli chcesz pisać program uniwersalny pod dwa systemy, żeby pod tymi dwoma systemami program został uruchomiony, to krótko mówiąc nie da się. Każdy system jest inny i to, co napiszesz pod jeden nie zostanie uruchomione na drugim, chyba, że jest to program typu "hello world". Odsyłam do poradnika:
http://www.student.chemia.uj.edu.pl/~mrozek/USl/oprogramowanie/dokumentacja/asm_pdf_linux.pdf
Przykładowe systemy: Linux, Windows, znacząco się od siebie różnią. Popatrz na przerwania w tych systemach. Systemy te również mają różne API (Application Programming Interface), biblioteki i cały zestaw software'u niekompatybilnego ze sobą. Jedyne, co chyba możesz zrobić to po napisaniu programu na windows'a spróbować uruchomić go na Wine w Linux'ie. Na jakimś emulatorze funkcji systemowych taki Jak wspomniany Wine możesz uruchomić swoje programy, które nie są kompatybline z systemem docelowym. Chociażby sama kompilacja jest inna (ta najpopularniejsza), czyli nasm -f elf32 ... jest inna niż nasm -f win32 .... Pliki wykonywalne, nagłówki to co widoczne dla oka i niewidoczne (ukryte (definicja pliku)) jest różne od siebie na różnych platformach.
https://en.wikipedia.org/wiki/INT_(x86_instruction)
http://bogdro.evai.pl/linux/przer80h_4.html
-Jaka jest różnica pomiędzy kompilatorami (NASM, MASM, FASM). Czy są różnice w składni?
Tak, różnice w składni są, ale moim zdaniem kosmetyczne (drobne). NASM np. nie wspiera niektórych instrukcji, takich jak:
LODS, MOVS, STOS, SCAS, CMPS, INS, OUTS.
https://www.nasm.us/doc/nasmdoc2.html
Przejrzyj sobie na jakie platformy możesz pisać w poniektórych assembler'ach, np. NASM support'uje między innymi (obsługuje takie systemy):
Windows, Linux, macOS, DOS, OS/2
Źródło:
https://en.wikipedia.org/wiki/Comparison_of_assemblers
Różnica np. pomiędzy MASM a NASM w składni:
W MASM musisz napisać tak, żeby zarezerwować sobie 64 bytes (bajty),
stack db 64 dup (?)
, a w NASM musisz tak:
stack resb 64
Źródło:
https://www.nasm.us/doc/nasmdoc2.html#section-2.2.5
Musisz też pamiętać, że na niektórych procesorach są trochę inne instrukcje, ale one powinny być ze sobą kompatybilne, ponieważ to przecież architektura x86 ew. x86_64 (rozszerzenie). Jeśli zdarzy się, że na Twoim procesorze nie ma lub jest niezgodne coś z procesorem Intel'a to musisz doczytać jak to wykonać na swoim procesorze, czyli przede wszystkim dokumentacja swojego procesora, ale to później na początku korzystaj z obu dokumentacji, czyli z Intel'a i AMD. Prawie wszystko w początkowej fazie (zestaw instrukcji, itp.) jest ze sobą zgodne może jakiś procent jest, że coś nie jest. Im bardziej zaawansowanych będziesz używał instrukcji tym może okazać się, że ta instrukcja nie jest wspierana przez Twój procesor. Najczęściej jest tak, że te technologie są takie same lub podobne, ale np. coś jest bardziej wydajne od drugiego. Czyli np. processor musi zużyć więcej/mniej czasu aby coś obliczyć, bo np. u procesora AMD techonologia 3Dnow! jest gorzej/lepiej zoptymalizowana itp.. Z tego, co wyczytałem, to procesory AMD i Intel dbają o wsteczną kompatybilność. Reasumując, wydaje mi się, że niekompatybilność procesorów AMD i Intel to jakieś kilka procent.
https://en.wikipedia.org/wiki/X86
https://www.quora.com/Will-an-AMD-processor-run-all-of-the-software-that-an-Intel-processor-can
Cytat (z powyższego link'a (quora)):
"If you mean: “Is it possible to construct a program that will only run on an Intel CPU and not on an AMD CPU?” The answer to that is also “Yes.”"
W procesorach Intel'a masz MMX, a u AMD 3DNow!, jeśli chodzi o rozszerzenie instrukcji (obliczenia zmiennoprzecinkowe).
-Czego potrzebuję żeby zacząć pisać program (Mój system to windows 7 professional, procesor to
AMD FX(tm)-9370)
Przede wszystkim "samozaparcia". Jeszcze będziesz potrzebował:
- assembler (NASM)
- compiler (gcc)
- linker (ld)
Podałem tutaj przykład NASM, gcc, ld. Ale nic nie stoi na przeszkodzie, abyś mógł używać innego assemblera, kompilatora, linkera.
Zakładam, że będziesz na początku używał tych podstawowych instrukcji bez rozszerzeń, czyli z x86, a nie np. z x86_64 oraz bez MMX, 3Dnow!, itp..
Na początek (template)/(szablon) programu z użyciem main:
global _main
extern _printf
section .data
txt: dd 'Hello, World', 0
fmt: db '%s', 0
section .text
_main:
push txt
push fmt
call _printf
add esp, 8
ret
section .bss
Poczytaj o "calling conventions", ponieważ nie zawsze Ty będziesz czyścił po sobie dane na stosie. Również sprawdź sobie kolejność przekazywania parametrów np. na stosie; w niektórych językach konwencja jest taka, że przekazuje się parametry (argumenty funkcji) od prawej do lewej a w niektórych od lewej do prawej. Wywoływany _printf z biblioteki chyba C musisz podać od prawej do lewej, czyli najpierw tekst do wyświetlenia, a później format, a nie odwrotnie W Pascal'u podobno wywołuje się funkcje podając argumenty od lewej do prawej, ale to musiałby(m/ś) sprawdzić.
Musisz pamiętać, że gdy wywołujesz funkcje z API, to musisz wiedzieć coś o typach, np. ile mają bitów. Gdybym teraz napisał zamiast fmt: db '%s', 0; to fmt: dd '%s', 0. To wtedy byłby to chyba (UB) - undefined behavior (niezdefiniowane zachowanie) lub program nie działałby jak należy.
Syntax _printf:
int printf ( const char * format, ... );
Typ char ma 8 bitów, więc w kodzie assembly x86 użyłem db - pseudo-instrukcji, a nie jakiejś innej.
db - byte (8-bit)
dw - word (16-bit)
dd - dword (double-word) (32-bit)
Źródło: http://www.cplusplus.com/reference/cstdio/printf/
Zatem, więc trzeba patrzeć na syntax (składnie) funkcji w tym przypadku (case) _printf. Piszę z podkreśleniami, bo żeby pisać bez nich to musiałbym chyba jakieś flagi, czy coś dodać podczas kompilacji.
A kompilacja wygląda tak na 32 bit:
nasm -f win32 name_file.asm && gcc name_file.obj && a
Jeśli zechciałbyś własno napisaną funkcję użyć w assembly x86, to musisz najpierw skompilować z opcją -c i później dołączyć skompilowany plik tak:
Kompilacja z opcją -c (plik bez main):
gcc -c name_file2.c
Całość:
nasm -f win32 name_file.asm && gcc name_file.obj name_file2.o -o a && a
Assembler np. Nasm ściągasz stąd:
https://www.nasm.us/pub/nasm/releasebuilds/2.14/
32-bit lub 64. I dalej:
https://gcc.gnu.org/install/binaries.html http://www.mingw.org/
Np. wersję 32-bit:
https://osdn.net/projects/mingw/releases/
Linker będziesz mieć ld, bo taki razem z gcc będziesz mieć zainstalowany.
Pamiętaj, żeby ustawić plik z BOM, ponieważ bez BOM wyrzuci błąd. Możliwe, iż bez BOM też dałoby radę kompilować plik, ale to już trzeba by było kombinować zapewne.
Dokumentacje:
https://developer.amd.com/resources/developer-guides-manuals/
https://software.intel.com/en-us/articles/intel-sdm