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

Odpowiedz Nowy wątek
2006-08-01 20:44
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.


"(2b || !(2b)) == question" W. Shakespeare

Pozostało 580 znaków

2006-08-02 11:23
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;

<span style="color: blue">"Kolarstwo to jedna z najtrudniejszych dyscyplin sportu. Nawet najgorszy kolarz jest wciąż wybitnym sportowcem."
s.p. Marco Pantani
</span>

Pozostało 580 znaków

2006-08-02 11:34
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/S[...]kt03-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


Nie ma ludzi zdrowych psychicznie, są tylko źle zbadani...

Pozostało 580 znaków

2006-08-02 12:20
jjj
0

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

mov ebx, buffer

Pozostało 580 znaków

2006-08-02 16:58
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...


"(2b || !(2b)) == question" W. Shakespeare

Pozostało 580 znaków

2006-08-03 17:54
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.

Pozostało 580 znaków

2006-08-03 19:02
0

chyba masz również źle zapisane odwołanie do pamięci : http://rainbow.mimuw.edu.pl/S[...]-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>


Nie ma ludzi zdrowych psychicznie, są tylko źle zbadani...

Pozostało 580 znaków

2006-08-05 20:45
0

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


"(2b || !(2b)) == question" W. Shakespeare

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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