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[i];
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[i]; */
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
zadánío.jpg


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[i] */
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/windows-hardware/drivers/debugger/x64-architecture :
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

Kód: Vybrat vše

mov [rbx], 0

změnit na něco jako

Kód: Vybrat vše

mov dword ptr [rbx], 0


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[i] */
add rax,8 /* posun ukazatele v poli*/

cmp rbx, rcx /*porovnání pole[i] a pocetBinu*/
jb prikaz /*pokud je pole[i] 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 :/