Avatar
tomekmichalhu:

Dobrý den, nedaří se mi najít jak se zapisuje assemblerový kód v code::blocks s GNU GCC. zkoušel jsem snad věchny možný kombinace (asm, _asm, __asm, __asm__, kulatý i množinový závorky) ale furt se mi to nedaří. vytvořil jsem si 2 proměnné int A a B a pomocí "mov A,B" jsem je chtěl sečíst, ale program se ani nepřeložil. nevíte někdo jak na to?

 
Odpovědět 4. března 14:20
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na tomekmichalhu
Filip Šohajek:

Pošli kód a chybovou hlášku.

 
Nahoru Odpovědět 4. března 15:11
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na tomekmichalhu
Martin Dráb:

Problém je také v tom, že ani na IA32 ani na AMD64 (x64) neexistuje instrukce přesunu dat mezi dvěma proměnnými (místy v paměti). Vždy musí být alespoň jeden operand registr nebo konstanta.

Assembler by měl jít vkládat přes __asm (jednoinstrukční varianta) resp. _asm { ... } (více instrukční varianta.

Co se týče syntaxe instrukcí, GCC (alespoň podle mých zkušeností a https://www.ibiblio.org/…y-HOWTO.html) užívá syntaxe AT&T, kterářto mi přijde zbytečně nepřehledná a ukecaná (na rozdíl od Intel syntaxe, kde ale člověk řeší v podstatě jen jednu architekturu).

EDIT:
Aha, takže pro vkládání Assembleru se užívá asm() či __asm__().

Editováno 4. března 15:48
Nahoru Odpovědět  +1 4. března 15:46
2 + 2 = 5 for extremely large values of 2
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na Martin Dráb
Filip Šohajek:

Doplním, že GCC lze přinutit k používání Intelovské syntaxe dvěma způsoby:

asm(".intel_syntax noprefix");

nebo volbou -masm=intel v kompilátoru.

 
Nahoru Odpovědět  +1 4. března 15:55
Avatar
tomekmichalhu:

tak jsem to předělal na

asm(
    ".intel_syntax noprefix \n\t"
    "mov eax,(a) \n\t"
    "add (b),eax"
    );

a píše to:

||=== Build: Debug in ASMTest (compiler: GNU GCC Compiler) ===|
/home/thugmek/Dokumenty/code::blocks/asmtest/ASMTest/main.cpp||In function ‘int main()’:|
/home/thugmek/Dokumenty/code::blocks/asmtest/ASMTest/main.cpp|5|warning: unused variable ‘a’ [-Wunused-variable]|
/home/thugmek/Dokumenty/code::blocks/asmtest/ASMTest/main.cpp|6|warning: unused variable ‘b’ [-Wunused-variable]|
/tmp/ccwoiWYB.s|31|Error: no such instruction: `movl $0,%eax'|
||=== Build failed: 1 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|

bez prvního řádku to píše:

||=== Build: Debug in ASMTest (compiler: GNU GCC Compiler) ===|
/home/thugmek/Dokumenty/code::blocks/asmtest/ASMTest/main.cpp||In function ‘int main()’:|
/home/thugmek/Dokumenty/code::blocks/asmtest/ASMTest/main.cpp|5|warning: unused variable ‘a’ [-Wunused-variable]|
/home/thugmek/Dokumenty/code::blocks/asmtest/ASMTest/main.cpp|6|warning: unused variable ‘b’ [-Wunused-variable]|
/home/thugmek/Dokumenty/code::blocks/asmtest/ASMTest/main.cpp|11|Error: too many memory references for `mov'|
/home/thugmek/Dokumenty/code::blocks/asmtest/ASMTest/main.cpp|12|Error: too many memory references for `add'|
||=== Build failed: 2 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|
 
Nahoru Odpovědět 4. března 18:26
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na tomekmichalhu
Martin Dráb:

Co zkusit tohle?

asm(
    ".intel_syntax noprefix \n\t"
    "mov eax, dword ptr [a] \n\t"
    "add dword ptr [b], eax"
    );

Předpokládám, že a a b jsou 32bitová celá čísla. Případně zkus vynechat slovo ptr.

Nahoru Odpovědět 5. března 13:49
2 + 2 = 5 for extremely large values of 2
Avatar
Odpovídá na Martin Dráb
tomekmichalhu:

furt to píše to samý, nejde to ani když jsou čísla int, ani když jsou char

 
Nahoru Odpovědět 5. března 14:08
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na tomekmichalhu
Filip Šohajek:
asm volatile (
    ".intel_syntax noprefix;"
    "add %%eax, %%ebx;"
    :"=a" (a)
    :"b" (b)
);

Ty dolní argumenty znamenají, že se tyto proměnné přesunou do registru EAX (a) a výsledek se uloží do registru EBX (b), který se přesune do proměnné b.
Ohledně inline asm doporučuji dokumentaci GCC:
https://gcc.gnu.org/…-with-C.html

Editováno 5. března 14:32
 
Nahoru Odpovědět 5. března 14:32
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na Filip Šohajek
Filip Šohajek:

Pardon, moje chyba. Výsledek se samozřejmě neuloží do EBX ale do EAX. EBX je jen vstupní parametr.

 
Nahoru Odpovědět 5. března 14:38
Avatar
tomekmichalhu:

teď se to sice přeloží, ale nic to nesečte. Moc tomu nerozumím, kde se vezmou hodnoty v registrech?

 
Nahoru Odpovědět 5. března 15:17
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na tomekmichalhu
Filip Šohajek:

Sečte, pošli celý kód. Hodnoty se tam ocitnou pomocí těch parametrů "=a"(a) (Zapiš hodnotu a do EAXu a na konci bloku přesuň hodnotu z EAXu do a) a "b"(b) (Zapiš hodnotu b do EBX) . Přečti si tu dokumentaci, co jsem ti posílal.

Editováno 5. března 15:20
 
Nahoru Odpovědět 5. března 15:19
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 11 zpráv z 11.