Asembler wypisywanie helloworld

QU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
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?

Kopiuj
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

vpiotr
  • Rejestracja: dni
  • Ostatnio: dni
1

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

Kopiuj
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

QU
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 34
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?

Kopiuj
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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.