[Asm/C++] Konwersja kodu asm Intela do AT&T

0

Siema.
Mam pewien problem, mianowicie: próbuję przerobić niewielki fragment kodu assemblerowego napisanego w składni Intel'owskiej na kod w notacji AT&T ale mi nie za bardzo wychodzi, ciągle dostaję jakieś błędy kompilatora wiele z nich już poprawiłem ale reszty nie dam rady.
Oto kod:

//buffer to wskaźnik do danych wyciągniętych z bitmapy(tylko obrazek bez nagłówka)
//size to rozmiar tej bitmapy
void flipIt(void* buffer, unsigned int size)  // Flips The Red And Blue Bytes (256x256)
{
	void* b = buffer;	// Pointer To The Buffer
	//poniższa forma dla kompilatora GCC
	asm("movl $_size, %ecx\n\t" //?
		"movl $_b, %ebx\n\t" //?
		"label:\n\t"
			"movb 0(,%ebx,), %al\n\t"
			"movb 2(,%ebx,), %ah\n\t"
			"movb %al, 2(,%ebx,)\n\t"
			"movb %ah, 0(,%ebx,)\n\t"
			
			"addl $3, %ebx\n\t"
			"decl %ecx\n\t"
			"jnz label\n\t");
	//poniższa forma dla kompilatora VC++ lub Borland'a
	/*__asm								// Assembler Code To Follow
	{		//w miejscu size poniżej było 256*256
		mov ecx, size					// Set Up A Counter (Dimensions Of Memory Block)
		mov ebx, b						// Points ebx To Our Data (b)
		label:							// Label Used For Looping
			mov al,[ebx+0]				// Loads Value At ebx Into al
			mov ah,[ebx+2]				// Loads Value At ebx+2 Into ah
			mov [ebx+2],al				// Stores Value In al At ebx+2
			mov [ebx+0],ah				// Stores Value In ah At ebx
			
			add ebx,3					// Moves Through The Data By 3 Bytes
			dec ecx						// Decreases Our Loop Counter
			jnz label					// If Not Zero Jump Back To Label
	}*/
}

A teraz błędy kompilatora i linkera:

files.cpp: In function `void flipIt(void*, unsigned int)':
files.cpp:6: warning: unused variable 'b'
Linking...
D:\dokumenty\programowanie\zrodla\GreenHell2\..\GreenHell_Debug\files.o(.text+0x175): In function `Z6flipItPvj':
D:\dokumenty\programowanie\zrodla\GreenHell2\files.cpp:18: undefined reference to `size'
D:\dokumenty\programowanie\zrodla\GreenHell2\..\GreenHell_Debug\files.o(.text+0x17a):D:\dokumenty\programowanie\
zrodla\GreenHell2\files.cpp:18: undefined reference to `b'
collect2: ld returned 1 exit status

Prawie w ogóle się nie znam na assemblerze a kod ten bardzo mi się przyda, gdyż piszę pewien program używający OpenGL'a w którym jest potrzeba szybkiego zamieniania formatu kolorów BGR na RGB a powyższa funkcja ma za zadanie właśnie to robić.

Ps. Szukałem już wszędzie czegoś na temat assemblera i AT&T ale to co znalazłem było niestety niewystarczające.

Z góry bardzo dziękuję za pomoc.

0

Mam takie coś w delphi. Przetłumacz sobie, jak nie dasz rady to pisz. Pomożemy.

procedure SwapRGB(data : Pointer; Size : Integer);
asm
  mov ebx, eax
  mov ecx, size

@@loop :
  mov al,[ebx+0]
  mov ah,[ebx+2]
  mov [ebx+2],al
  mov [ebx+0],ah
  add ebx,3
  dec ecx
  jnz @@loop
end;
0

Oleksy_Adam przecież on miał to w komentarzu co mu podałeś ;p Według mnie źle podajesz parametry z procedury do kodu, nie ma czegośtakiego jak $_size :) poczytaj sobie tutaj jak to zrobić :

http://rainbow.mimuw.edu.pl/SO/Projekt03-04/temat2-g6/inline.html

chyba tak powinno działac:

//buffer to wskaźnik do danych wyciągniętych z bitmapy(tylko obrazek bez nagłówka)
//size to rozmiar tej bitmapy
void flipIt(void* buffer, unsigned int size)  // Flips The Red And Blue Bytes (256x256)
{
        void* b = buffer;        // Pointer To The Buffer
        __asm__("label:\n\t"
                        "movb 0(,%ebx,), %al\n\t"
                        "movb 2(,%ebx,), %ah\n\t"
                        "movb %al, 2(,%ebx,)\n\t"
                        "movb %ah, 0(,%ebx,)\n\t"
                       
                        "addl $3, %ebx\n\t"
                        "decl %ecx\n\t"
                        "jnz label\n\t"
                :
                : "c"(size), "b"(b));
}

Chyba będzie działać, nie sprawdzałem

0

Po co tam to 'b', ładujesz od razu:

mov ebx, buffer

0

ADuch faktycznie źle przekazywałem te parametry... jednak po próbie kompilacji wersji kodu którą podałeś miałem, aż 16 błędów kompilatora... Poszukałem na tej stronie do której linka zamieściłeś i jeszcze na paru innych ale rozwiązania problemu nie znalazłem, co najwyżej udało mi się poprawić kod tak, że teraz mam tylko 8 błędów..... :-/
Zamieszczam trochę poprawiony kod:

__asm__(
	"label:\n\t"
		"movb 0(%1), %al\n\t" //zmiana %ebx na %1
		"movb 2(%1), %ah\n\t"
		"movb %al, 2(%1)\n\t"
		"movb %ah, 0(%1)\n\t"
		
		"addl $3, %1\n\t" //zmiana %ecx na %0
		"decl %0\n\t"
		"jnz label\n\t"
         :
         : "c"(size), "b"(b));    //%0==size,  %1==b ???

Błędy kompilatora:

files.cpp:19: error: invalid `asm': operand number missing after %-letter
files.cpp:19: error: invalid `asm': operand number missing after %-letter
files.cpp:19: error: invalid `asm': operand number missing after %-letter
files.cpp:19: error: invalid `asm': operand number missing after %-letter
{standard input}: Assembler messages:
{standard input}:623: Error: too many memory references for `mov'
{standard input}:624: Error: too many memory references for `mov'
{standard input}:625: Error: too many memory references for `mov'
{standard input}:626: Error: too many memory references for `mov'

Z czego 19 linia w kodzie to ostatnia linia kodu assemblera, czyli linia: : "c"(size), "b"(b));
Domyślam się, że te 4 pierwsze błędy dotyczą linni kodu zawierającymi rejestry %ah i %al nie mam pojęcia co z pozostałymi 4 błędami ale może znikną, jeżeli się poprawi te cztery pierwsze... Jednak nie mam pojęcia jak to zrobić...
Może bardzo mieszam ale to dlatego, że jestem bardzo niewyspany.

Pozdrawiam

Ps. Oleksy_Adam ten kod który mam w komentarzu nie działa z tego powodu, że nie używam kompilatora Borland'a czy VC++ a kompilatora GCC, który z tego co mi wiadomo nie akceptuje normalnej składni assemblera Intelowskiego a tylko składnię AT&T i właśnie w tym tkwi cały problem...

0
Joker napisał(a)

Błędy kompilatora:

files.cpp:19: error: invalid `asm': operand number missing after %-letter
files.cpp:19: error: invalid `asm': operand number missing after %-letter
files.cpp:19: error: invalid `asm': operand number missing after %-letter
files.cpp:19: error: invalid `asm': operand number missing after %-letter
{standard input}: Assembler messages:
{standard input}:623: Error: too many memory references for `mov'
{standard input}:624: Error: too many memory references for `mov'
{standard input}:625: Error: too many memory references for `mov'
{standard input}:626: Error: too many memory references for `mov'

W rozszerzonym gcc-assemblerze nazwy rejestrów poprzedzasz %%, np. %%eax.

0

chyba masz również źle zapisane odwołanie do pamięci : http://rainbow.mimuw.edu.pl/SO/Projekt03-04/temat2-g3/asmintel/prezentacja.html

adres(wskaznikbazowy,wskaznikdoindeksu,skalaindeksowania)
Odpowiada to następującemu wyrażeniu w konwencji notacyjnej Intel.
[wskaznikbazowy + wskaznikdoindeksu*skalaindeksowania + adres]

a więc:
0(,%ebx, ) = [0 + ebx0 + 0] = [0]
2(,%ebx,) = [0 + ebx
0 + 2] = [2]
Przynajmniej tak mi się wydaje ...

Ten kod na pewno działa ( sprawdzałem w DJGPP ):

void flipIt(void* buffer, unsigned int size)  // Flips The Red And Blue Bytes (256x256)
{
        void* b = buffer;        // Pointer To The Buffer
        __asm__("label:\n\t"
                        "movb 0(%%ebx), %%al\n\t"
                        "movb 2(%%ebx), %%ah\n\t"
                        "movb %%al, 2(%%ebx)\n\t"
                        "movb %%ah, 0(%%ebx)\n\t"
                       
                        "addl $3, %%ebx\n\t"
                        "decl %%ecx\n\t"
                        "jnz label\n\t"
                :
                : "c"(size), "b"(b));
}

main()
{
 char buf[6]={1,2,3,4,5,6};
 int i;

 flipIt(buf, 2);
 printf("\n");
 for(i=0; i<6; i++)
  printf("%i ",buf[i]);
 while(!kbhit());
}

</cpp>
0

Przeogromne dzięki sam bym tego nie był w stanie zrobić. Dzięki!

1 użytkowników online, w tym zalogowanych: 0, gości: 1