assemblykoodi gcc:ssä (Windows; 32-bit)
int main(void)
{
unsigned int R1 = 11, R2 = 40, R3 = 0xfffffff;
unsigned long long int summa;
__asm__ __volatile__(
" push EDI ;\n\t"
" xor edi,edi ;\n\t"
"addl %�x,%�x ;\n\t"
"adcl 0,%�i ;\n\t"
"addl %�x,%�x ;\n\t"
"adcl 0,%�i ;\n\t"
"movl %�i,%�x ;\n\t"
// EDX:EAX = summa(eax, edx, ecx)
" pop EDI ;\n\t"
" mov 1, %%ESI ;\n\t"
:"=a"(summa)
:"a"(R1), "d"(R2), "c"(R3)
: "%%ESI" // clobber list.
);
printf("Summa on=%I64u\n\t", summa); // OS: Windows, 32-Bit. Linuxissa: %llu.
return 0;
}
Toimiiko ylläoleva oikein?
Sen olisi tarkoitus laskea 64 -bittinen summa kolmesta 32-bittisestä luvusta:
sama kuin summa = R1 + R2 + R3,
mutta siten, että tuloksen ei sallita "pyörähtää ympäri" KUN 32 -BITTINEN LUKUALUE Ylittyy.
Tarkoitus siis olisi että gcc -kääntäjä huolehtii siitä, että:
välittömästi ennen asm -lohkon alkua:
muuttuja R1 ladataan rekisteriin EAX.
muuttuja R2 ladataan rekisteriin EDX.
muuttuja R3 ladataan rekisteriin EDX.
ja juuri asm -lohkon jälkeen:
rekisteriparin EDX:EAX sisältö tallennetaan muuttujaan summa.
Ja ihan testitarkoituksessa:
Kerrotaan C -kääntäjälle, että asm -lohko käyttää rekisteriä ESI eikä vaivaudu palauttamaan sen arvoa alkuperäiseksi.
Toimiiko koodi tarkoitetulla tavalla?
Entä, mitä pitäisi muuttaa, jotta assembly -koodin voisi kirjoittaa intel -syntaksilla tuon at&t sijasta ?
{
unsigned int R1 = 11, R2 = 40, R3 = 0xfffffff;
unsigned long long int summa;
__asm__ __volatile__(
" push EDI ;\n\t"
" xor edi,edi ;\n\t"
"addl %�x,%�x ;\n\t"
"adcl 0,%�i ;\n\t"
"addl %�x,%�x ;\n\t"
"adcl 0,%�i ;\n\t"
"movl %�i,%�x ;\n\t"
// EDX:EAX = summa(eax, edx, ecx)
" pop EDI ;\n\t"
" mov 1, %%ESI ;\n\t"
:"=a"(summa)
:"a"(R1), "d"(R2), "c"(R3)
: "%%ESI" // clobber list.
);
printf("Summa on=%I64u\n\t", summa); // OS: Windows, 32-Bit. Linuxissa: %llu.
return 0;
}
Toimiiko ylläoleva oikein?
Sen olisi tarkoitus laskea 64 -bittinen summa kolmesta 32-bittisestä luvusta:
sama kuin summa = R1 + R2 + R3,
mutta siten, että tuloksen ei sallita "pyörähtää ympäri" KUN 32 -BITTINEN LUKUALUE Ylittyy.
Tarkoitus siis olisi että gcc -kääntäjä huolehtii siitä, että:
välittömästi ennen asm -lohkon alkua:
muuttuja R1 ladataan rekisteriin EAX.
muuttuja R2 ladataan rekisteriin EDX.
muuttuja R3 ladataan rekisteriin EDX.
ja juuri asm -lohkon jälkeen:
rekisteriparin EDX:EAX sisältö tallennetaan muuttujaan summa.
Ja ihan testitarkoituksessa:
Kerrotaan C -kääntäjälle, että asm -lohko käyttää rekisteriä ESI eikä vaivaudu palauttamaan sen arvoa alkuperäiseksi.
Toimiiko koodi tarkoitetulla tavalla?
Entä, mitä pitäisi muuttaa, jotta assembly -koodin voisi kirjoittaa intel -syntaksilla tuon at&t sijasta ?
int main(void)
{
unsigned int R1 = 11, R2 = 40, R3 = 0xfffffff;
unsigned long long int summa;
__asm__ __volatile__(
" push EDI ;\n\t"
" xor edi,edi ;\n\t"
"addl @@edx,@@eax ;\n\t"
"adcl 0,@@edi ;\n\t"
"addl @@ecx,@@eax ;\n\t"
"adcl 0,@@edi ;\n\t"
"movl @@edi,@@edx ;\n\t"
// EDX:EAX = summa(eax, edx, ecx)
" pop EDI ;\n\t"
" mov 1, @@ESI ;\n\t"
:"=a"(summa)
:"a"(R1), "d"(R2), "c"(R3)
: "@@ESI" // clobber list.
);
printf("Summa on=@I64u\n\t", summa); // OS: Windows, 32-Bit. Linuxissa: @llu.
return 0;
}
VALITETTAVASTI suomi24 -forumohjelmisto sekoilee jälleen !
Alkuperäisessä viestissä C -lähdekoodissa olleet prosenttimerkit (jotka ikävä kyllä kuuluvat at&t syntaksiin assemblykielessä) aiheuttivat koko viestin sotkeutumisen.
Tässä sama viesti uudelleen siten, että jokainen prosenttimerkki on korvattu ät -merkillä.
{
unsigned int R1 = 11, R2 = 40, R3 = 0xfffffff;
unsigned long long int summa;
__asm__ __volatile__(
" push EDI ;\n\t"
" xor edi,edi ;\n\t"
"addl @@edx,@@eax ;\n\t"
"adcl 0,@@edi ;\n\t"
"addl @@ecx,@@eax ;\n\t"
"adcl 0,@@edi ;\n\t"
"movl @@edi,@@edx ;\n\t"
// EDX:EAX = summa(eax, edx, ecx)
" pop EDI ;\n\t"
" mov 1, @@ESI ;\n\t"
:"=a"(summa)
:"a"(R1), "d"(R2), "c"(R3)
: "@@ESI" // clobber list.
);
printf("Summa on=@I64u\n\t", summa); // OS: Windows, 32-Bit. Linuxissa: @llu.
return 0;
}
VALITETTAVASTI suomi24 -forumohjelmisto sekoilee jälleen !
Alkuperäisessä viestissä C -lähdekoodissa olleet prosenttimerkit (jotka ikävä kyllä kuuluvat at&t syntaksiin assemblykielessä) aiheuttivat koko viestin sotkeutumisen.
Tässä sama viesti uudelleen siten, että jokainen prosenttimerkki on korvattu ät -merkillä.
Ensinnäkin miksi laitat push-komennolla tuon EDI-rekisterin pinoon jota et käytä lainkaan?
Aivan joo mutta ei kannattaisi indeksirekistereitä, hitaampia käyttää tuolla tavoin, olisit käyttänyt laskennassa rekisteriä EEAX.
Aivan joo mutta ei kannattaisi indeksirekistereitä, hitaampia käyttää tuolla tavoin, olisit käyttänyt laskennassa rekisteriä EEAX.
Kerro mielipiteesi