Stránka 1 z 2
Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 14:48
od Zakk
Zdravím.
Dělám úkol z assembleru a nevím si rady.
Problém je v tom, že nevím, jak zapsat do pole.
Například mám pole pojmenované "hist" a chtěl bych do pole přiřadit nulu ( na místo, kde mám zrovna pointer).
Takže si pointer nastavím na začátek pole
lea rbx, hist[rip] /* pointer na začátek pole histogram,*/
A v cyklu mu přiřazuju 0.
cycle:
mov [rbx], 0 /* prvku pole přiřaď nulu */ -- tenhle řádek je špatně
add rbx,8 /* posun ukazatele*/
dec rcx /* zmenšení iterátoru* i++(respektive v našem případě i--)/
jnz cycle /* skok na cyklus*/
a prostě nevím, jak to zapsat zkoušel jsem ještě: mov, hist[rbx]... mov, hist[rip].. prostě nevím, jak tohle zapsat a vygooglit se mi taky moc nic nepodařilo.
Budu vděčný za každou radu.
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 17:11
od satik
RIP je registr s offsetem pro aktuálně prováděnou instrukci, ten tam určitě používat nechceš. Takze ve výsledku ukládáš do rbx nějakou celkem náhodnou adresu, místo začátku pole.
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 17:32
od Zakk
Takže říkáš, že mám špatně tenhle řádek
lea rbx, hist[rip] /* pointer na začátek pole histogram,*
?
Pamatuju si, že takhle to ten učitel psal.
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 18:15
od satik
Určitě tam neměl RIP nebo se upsal, smysl by dávalo RSP.
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 18:37
od Zakk
Opravdu to tam takhle psal a nebylo to jen jednou a myslím, že mu to i fungovalo.
Tady mám vzorový příklad ( přepsat z javy do asm x86_64)
long arr_a[] = { 10, 20, 30, 40, 0 };
long i = 0;
long y = 0;
long v;
do {
v = arr_a
;
y += v;
i++;
} while (v != 0);
reseni:
xor rax, rax /* y = 0 */
lea rbx, arr_a[rip] /* rbx <- adresa pole arr_a */
cycle:
mov rcx, [rbx] /* v = arr_a; */
add rax, rcx /* y += v; */
add rbx, 8 /* i++ */
test rcx, rcx
jnz cycle /* while (v != 0) */
call print_rax
jinak můj příklad vypadá takhle
a takhle je moje prozatimní řešení
lea rax, pole[rip] /* pointer na začátek pole pole*/
lea rbx, hist[rip] /* pointer na začátek pole histogram,*/
mov rcx, pocetBinu /* iterátor pocetBinu do rcx kvůli cyklu */
cycle:
mov [rbx], 0 /* prvku pole přiřaď nulu */
add rbx,8 /* posun ukazatele*/
dec rcx /* zmenšení iterátoru* i++(respektive v našem případě i--)/
jnz cycle /* skok na cyklus*/
/*cyklus na vynulování části pole možná zybtečný, když je pole inicializované na smaé nuly ?? */
mov rdx, delka /* nastaví iterátor podle délky */
cycle2:
mov rbx, [rax] /*přiřadí do rbx,hodnotu pole na pozici i (kde je pointer), prvek=pole
*/
add rax,8 /* posun ukazatele v poli*/
/* if */
cmp prvek[rip], pocetBinu[rip] /*porovnání proměnné prvek a proměnné pocetBinu*/
jb prikaz /*pokud je prvek menší proveď prikaz*/
prikaz:
add [rbx],1 /* zvětšení hist na pozici kde je pointer (hist[prvek]++) */
dec rdx /*zmenšení iterátoru* i++(respektive v našem případě i--)*/
jnz cycle2 /*skok na cyklus*/
/*tisk*/
call print_all
V těch červených řádcích to hlásí chybu a nejde to zkompilovat.
Možná to mám celé uplně špatně.
Co by si mi teda poradil ?
Díky
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 19:17
od satik
Hm, koukam, ze v x64 je mozny nejak pouzivat rip i na adresovani, viz.
https://docs.microsoft.com/en-us/window ... chitecture :
x64 provides a new rip-relative addressing mode. Instructions that refer to a single constant address are encoded as offsets from rip. For example, the mov rax, [addr] instruction moves 8 bytes beginning at addr + rip to rax.
Ale nikdy jsem to nepoužil, asm aktivně už skoro vůbec nepoužívám :)
Vadí tomu nejspíš to, že tam nemáš velikost, musíš tomu dát vědět, jak velkej blok dat tam chceš.
Takže kód
změnit na něco jako
Některej kompilátor to může chtít napsaný třeba velkýma písmenama apod, to musíš do dokumentace.
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 20:20
od Zakk
Zdá se, že to pomohlo díky moc.
Ale pořád nevím, co s tím řádkem:
cmp prvek[rip], pocetBinu[rip]/*porovnání proměnné prvek a proměnné pocetBinu*/
jb prikaz /*pokud je prvek menší proveď prikaz*/
prikaz:
add [rbx],1 /* zvětšení hist na pozici kde je pointer (hist[prvek]++) *
a píše mi to " too many memory references for cmp"
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 20:51
od satik
vytahej ty hodnoty z polí do registrů
Dodatečně přidáno po 8 minutách 10 vteřinách:
nebo možná stačí i jen jednu, ono ve většině operací (možná všude?) můžeš do paměti šahat maximálně na jednom místě, zbylá hodnota musí bejt konstanta nebo registr
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 22:34
od Zakk
Tak když dám jednu do registru tak je to lepší (druhou už nevím,kam bych nacpal, když mám zaplněné rax, rbx, rcx i rdx).
Pořád se tomu ale něco nezdá
student.o:student.as:(.text+0x16): relocation truncated to fit: R_X86_64_32S against `.data'
student.o:student.as:(.text+0x2b): relocation truncated to fit: R_X86_64_32S against `.data'
collect2: error: ld returned 1 exit status
make: *** [Makefile:11: main] Chyba 1
Už asi otravuju, ale opravdu nevím jak to celé vyřešit..
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 22 dub 2018 23:03
od satik
Tech registru mas hromadu, muzes vybirat, jen bacha at nepouzijes nakej, co ma naky jiny vyuziti, takze idealne pouzit ty s cislama :)
https://docs.microsoft.com/en-us/window ... chitecture
Pripadne stack, tam muzes jakejkoliv registr pushnout a pak popnout.
To relocation netusim, jestli to nahodou nesouvisi s tim vyuzitim RIP? Fakt netusim :)
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 23 dub 2018 20:23
od Zakk
Tak to bylo tím, že mi chybělo [rip], když jsem tahal ty proměnné do registrů.
mov rcx, pocetBinu[rip] /* pocetBinu do rcx */
mov rdx, delka[rip] /* nastaví iterátor podle délky */
Teď už se mi to zkompilovat podařilo. Ale spustit o nejde.. nemám tam teda ještě žádnej tisk, ale i tak vyhodí to
" make: * [Makefile:18: run] Segmentation fault (obraz paměti uložen)"
Celé jsem to trochu překopal něco jsme tam měl špatně, takže teď ten kód vypadá takle
lea rax, pole[rip] /* pointer na začátek pole pole*/
lea rbx, hist[rip] /* pointer na začátek pole histogram,*/
mov rcx, pocetBinu[rip] /* pocetBinu do rcx */
mov rdx, delka[rip] /* nastaví iterátor podle délky */
cycle2:
mov rbx, [rax] /*přiřadí do rbx,hodnotu pole na pozici i (kde je pointer), prvek=pole */
add rax,8 /* posun ukazatele v poli*/
cmp rbx, rcx /*porovnání pole a pocetBinu*/
jb prikaz /*pokud je pole menší proveď prikaz*/
prikaz:
add dword ptr [rbx],1 /* zvětšení hist na pozici kde je pointer (hist[prvek]++) */
dec rdx /*zmenšení iterátoru* i++(respektive v našem případě i--)*/
jnz cycle2 /*skok na cyklus*/
Zkoušel jsem dávat všude prity abych zjistil, kde se to pokazí a vypadá na řádek " jb prikaz".
Re: Assembler x64 ( pomoc s domácím úkolem)
Napsal: 23 dub 2018 20:37
od satik
jb prikaz
tady nedava smysl, skaces na dalsi radek, ale to samy se stane i kdyz neskocis
Trochu me tam vsude desej ty rip, spis bych tam misto nich, netusim, co presne delaji, asi bych to osobne psal bez nich :/