Diskuze: assembler v code::blocks s GNU GCC pod linuxem

Assembler assembler v code::blocks s GNU GCC pod linuxem

Aktivity (1)
Avatar
tomekmichalhu:4.3.2016 14:20

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.3.2016 14:20
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na tomekmichalhu
Filip Šohajek:4.3.2016 15:11

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

 
Nahoru Odpovědět 4.3.2016 15:11
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na tomekmichalhu
Martin Dráb:4.3.2016 15:46

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.3.2016 15:48
Nahoru Odpovědět  +1 4.3.2016 15:46
2 + 2 = 5 for extremely large values of 2
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na Martin Dráb
Filip Šohajek:4.3.2016 15:55

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.3.2016 15:55
Avatar
tomekmichalhu:4.3.2016 18:26

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.3.2016 18:26
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na tomekmichalhu
Martin Dráb:5.3.2016 13:49

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.3.2016 13:49
2 + 2 = 5 for extremely large values of 2
Avatar
Odpovídá na Martin Dráb
tomekmichalhu:5.3.2016 14:08

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

 
Nahoru Odpovědět 5.3.2016 14:08
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na tomekmichalhu
Filip Šohajek:5.3.2016 14:32
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.3.2016 14:32
 
Nahoru Odpovědět 5.3.2016 14:32
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na Filip Šohajek
Filip Šohajek:5.3.2016 14:38

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

 
Nahoru Odpovědět 5.3.2016 14:38
Avatar
tomekmichalhu:5.3.2016 15:17

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.3.2016 15:17
Avatar
Filip Šohajek
Redaktor
Avatar
Odpovídá na tomekmichalhu
Filip Šohajek:5.3.2016 15:19

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.3.2016 15:20
 
Nahoru Odpovědět 5.3.2016 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.