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 ?
Ilmianna
Jaa

1 Vastaus


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ä.
Ilmianna
Jaa

Vastaa alkuperäiseen viestiin

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 ?

5000 merkkiä jäljellä

Peruuta