Asembler wypisywanie helloworld

0

Cześć,
stawiam pierwsze kroki w asemblerze i napotkałem na problem. Miałem zmodyfikować kod z wyświetlania 5 razy Hello World na wyświetlanie tyle razy ile poda użytkownik poprzez klawiaturę. Pojawia się błąd przy linkowaniu:

hello.o: In function petla': hello.asm:(.text+0x4d): relocation truncated to fit: R_X86_64_8 against .data'

Prosiłbym o pomoc.
Tak w ogóle to są jakieś dobre poradniki zagraniczne z których można byłoby lepiej zrozumieć ten język?

section .data
napis:     	db 'Hello world!',10,0
dlugosc_napisu	equ $-napis      

liczba_iteracji:  db 0
liczba_iteracji_dl equ $-liczba_iteracji



section .bss
licznik: resb 1

section .text
	global _start


_start:

mov rax, 3
mov rbx, 0
mov rcx, [liczba_iteracji]
mov rdx, [liczba_iteracji_dl]


int 80h


mov	byte [licznik],0

petla:

inc	byte [licznik]
	mov rax,4		;funkcja systemowa (system call) nr 4: sys_write
	mov rbx,1		;stdout
	mov rcx,napis		;adres poczatku ciagu tekstowego
	mov rdx,dlugosc_napisu	;liczba znakow ASCII do wyswietlenia
	int 80h			;wywolanie przerwania sys. Linux

cmp	byte [licznik],liczba_iteracji
jnz	petla




	mov rax,1            	;funkcja systemowa (system call) nr 1: sys_exit
	mov rbx,0            	;return 0
	int 80h

1

Wersja trochę lepsza, która działa, ale tylko stałą liczbę razy:

section .data
napis:         db 'Hello world!',10
dlugosc_napisu    equ $-napis      
 
section .bss
    licznik: resb 1
    liczba_iteracji: resb 5
 
section .text
    global _start
 
 
_start:
 
    mov rax, 3
    mov rbx, 2
    mov rcx, liczba_iteracji
    mov rdx, 5
    int 80h
  
    mov    byte [licznik],0
    mov    byte [liczba_iteracji],3
 
petla:
 
    inc byte [licznik]

echo:    
    mov rax,4        ;funkcja systemowa (system call) nr 4: sys_write
    mov rbx,1        ;stdout
    mov rcx,napis        ;adres poczatku ciagu tekstowego
    mov rdx,dlugosc_napisu    ;liczba znakow ASCII do wyswietlenia
    int 80h            ;wywolanie przerwania sys. Linux

endpetla:
    mov al, byte [liczba_iteracji]
    cmp al, byte [licznik]
    jnz petla
 
koniec:

    mov rax,1                ;funkcja systemowa (system call) nr 1: sys_exit
    mov rbx,0                ;return 0
    int 80h

nasm -f elf64 test.asm
ld -s -o test64 test.o

Działa zawsze 3 razy, żeby działała zgodnie z zamierzeniem, to trzeba skonwertować liczbę wprowadzoną tekstową (w liczba_iteracji) na wartość binarną.
Dodałem więcej etykiet, dzięki czemu komunikaty błędów są sensowniejsze.

Edit: tu masz konwersję ASCII do int:
http://stackoverflow.com/questions/19461476/convert-string-to-int-x86-32-bit-assembler-using-nasm

0

Dzięki za pomoc. Zanim przejdę do konwersji ASCII do int, to może pierwsze coś łatwiejszego zrobię. Program ma wyświetlić litery od A do Z. Program działa, jednak nie wiem jak stworzyć w pętli_2 warunek.
Jeszcze jedno pytanie, czy jeśli będę używał funkcję scanf to także muszę konwertować ASCII na int?

section .data

	znak db 65
	koniec db 90
	spacja db 32
	spacja_dl equ $-spacja

section .text

global _start

_start:

petla:
	mov rax, 4
	mov rbx, 1
	mov rcx, znak
	mov rdx, 1
	int 80h
	
	mov rax, 4
	mov rbx, 0
	mov rcx, spacja
	mov rdx, spacja_dl
	int 80h
	
petla_2:

	inc byte [znak]
	mov al, [znak]    ; juz sobie poradziłem z tym i działa elegancko, ale nie wiem dlaczego nie można zrobić cmp [znak],[koniec]?
	cmp al, [koniec]
	jnz petla

nowa_linia:
	
	mov rax, 4
	mov rbx, 0
	mov rcx, linia
	mov rdx, 1
	int 80h



mov rax, 1
xor rbx, rbx
int 80h

1 użytkowników online, w tym zalogowanych: 0, gości: 1