Popiol |
Poison Headcrab |
|
|
Dołączył: 02 Lis 2005 |
Posty: 16 |
Przeczytał: 0 tematów
Ostrzeżeń: 0/5
|
Skąd: Wygiełzów |
|
|
|
|
|
|
No bo widzisz Dev C++ jest "inny", a żeby nikogo nie obrażać powiem orginalny. To, że int ma w devie 2 bajty, a w większości kompilatorów 4 to akurat szczegół. Wielkość inta chyba nawet nie jest ściśle określona w standardzie C++. Natomiast dużą odmiennością jest fakt korzystania ze składni AT&T assemblera, a nie jak wszyscy normalni ludzie ze składni Intela. Jakby tego było mało to dev nie przyjmuje bloku asm {...}. Tu trzeba napisać __asm("..."), a kolejne instrukcje oddzielać znakiem nowej linii, albo każdą instrukcje pisać w osobnym __asm("..."). No i jeszcze zmienne muszą być globalne, a wewnątrz kodu assemblera trzeba poprzedzać je znakiem _. Tak więc w końcu udało mi się napisać kod, który działa pod Dev C++:
Kod: | #include <iostream>
using namespace std;
long wynik, podstawa = 2, wykladnik = 5;
int main() {
__asm(
"mov $1, %eax\n"
"mov _wykladnik, %ecx\n"
"petla:\n"
"mull _podstawa\n"
"loop petla\n"
"mov %eax, _wynik");
cout<<wynik;
system("pause");
return 0;
} |
Jak widać nie za fajnie to wygląda. Dlatego proponuję zmianę kompilatora (Builder Personal 6 jest darmowy). Jeśli jednak ktoś uprze się przy devie to wyjaśnię podstawowe różnice w składni AT&T i Intela.
- stałe liczby, wpisane bespośrednio w kod, są poprzedzane znakiem $, np $1 zamiast 1.
- rejestry są poprzedzane znakiem %, np %ax zamiast ax
- nazwy etykiet i procedur po jmp i po call są poprzedzane znakiem *, np jmp *petla, zamiast jmp petla
- operandy w takich operacjach jak mov, czy add są zamienione kolejnością, np addl $4, %eax, zamiast add eax, 4
- do takich poleceń jak mov czy add dodaje się literę oznaczającą wielkość operandów, np mulb $4 oznacza mnożenie przez liczbę jednobajtową, mulw $4 przez dwubajtową, mull $4 przez czterobajtową
Kolejne różnice są nieistotne przy pisaniu wstawek assemblerowych:
- Przed dalekimi skokami i wywołaniami dodaje się literę l, np lcall $0000, $0000
- Wszystkie programy muszą być jednosegmentowe (dziwne nie?)
- Inaczej się wylicza adres, np -4(%ebp,%eax,4), zamiast [ebp + eax*4 - 4]
|
|