pRoGraMerZ


Forum pRoGraMerZ Strona Główna -> Assembler -> Wstawki assemblerowe w C, C++ Idź do strony 1, 2  Następny
Napisz nowy temat  Odpowiedz do tematu Zobacz poprzedni temat :: Zobacz następny temat 
Wstawki assemblerowe w C, C++
PostWysłany: Pią 23:52, 11 Lis 2005
Popiol
Poison Headcrab

 
Dołączył: 02 Lis 2005
Posty: 16
Przeczytał: 0 tematów

Ostrzeżeń: 0/5
Skąd: Wygiełzów





Programując w C, C++ czy Pascalu można wstawiać fragmnty kody napisane w assemblerze. Może to przyśpieszyć działanie pewnych operacji.

W C i C++ robi się to tak:

Kod:
int wynik, podstawa = 2, wykladnik = 5;
asm {
  mov eax, 1
  mov ecx, wykladnik
  petla:
    mul eax, podstawa
    loop petla
  mov wynik, eax
}


Wartość zmiennej wynik po wykonaniu tego kodu będzie wynosiła 2^5 czyli 32. Jak widać we wstawce assemblerowej można używać zmiennych zdefiniowanych w kodzie C/C++, co znacząco ułatwia programowanie. Tylko nie używajcie tu przerwań, bo mogą dziać się dziwne rzeczy. Miłej zabawy Smile.


Post został pochwalony 0 razy
Zobacz profil autora
PostWysłany: Sob 10:42, 19 Lis 2005
bednarz
Administrator

 
Dołączył: 20 Paź 2005
Posty: 6
Przeczytał: 0 tematów

Ostrzeżeń: 0/5





mam pytanie Dlaczego uzywasz rejestrow 32bitowych przeciez inty są 2 bajtowe ? A wogole to tobie dziala? Bo jak probowalem to pod DEVem skompilowac to bledy wyskakuja
kod wyglada tak:
Kod:
#include <iostream>
using namespace std;

int main(){

int wynik, podstawa = 2, wykladnik = 5;
asm {
  mov eax, 1
  mov ecx, wykladnik
  petla:
    mul eax, podstawa
    loop petla
  mov wynik, eax
}
cout<<wynik;
system("pause");
return 0;
}


a bledy takie:
Kod:
 `int main()':
5: error: expected `(' before '{' token

5: error: expected asm body before '{' token
:6: error: `mov' undeclared (first use this function)
6: error: (Each undeclared identifier is reported only once for each function it appears in.)
6: error: expected `;' before "eax"
7: error: expected `;' before "ecx"
9: error: `mul' undeclared (first use this function)
9: error: expected `;' before "eax"
10: error: `loop' undeclared (first use this function)
10: error: expected `;' before "petla"
11: error: expected `;' before "wynik"


moze trzeba dolączyć jakis plik naglówkowy Question


Post został pochwalony 0 razy
Zobacz profil autora
PostWysłany: Nie 0:23, 20 Lis 2005
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]


Post został pochwalony 0 razy
Zobacz profil autora
PostWysłany: Nie 12:39, 20 Lis 2005
bednarz
Administrator

 
Dołączył: 20 Paź 2005
Posty: 6
Przeczytał: 0 tematów

Ostrzeżeń: 0/5





Dzieki za wyjasniejnie A co do inta to jednak zajmuje 4 bajty wiec jak powiadala pewna pani nauczycielka ZWRACAM HONOR Smile


Post został pochwalony 0 razy
Zobacz profil autora
PostWysłany: Pią 0:09, 02 Lut 2007
eqalizer
Gość

 





dodaj do opcji kompilacji -masm=intel
Wstawki assemblerowe w C, C++
Forum pRoGraMerZ Strona Główna -> Assembler
Możesz pisać nowe tematy
Możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Wszystkie czasy w strefie EET (Europa)  
Strona 1 z 2  
Idź do strony 1, 2  Następny
  
  
 Napisz nowy temat  Odpowiedz do tematu  


fora.pl - załóż własne forum dyskusyjne za darmo
Powered by phpBB © 2001-2003 phpBB Group
Theme created by Vjacheslav Trushkin
Regulamin