I have matrix 5,5. I'm trying to print each column's even numbers total in an array(5). Can anyone help please? I got a segment error. Please don't tell me to start another language firstly. I'm trying this for almost 3 days. But I still couldn't find out the error. Please.
My expected answer is
2 8 8 0 24 0
This is my code:
bits 64;
%include "../io.asm"
%define write 1
%define stdout 1
%define exit 60
section .data
matr db 2,2,3,4,1
db 5,1,5,8,1
db 9,6,1,12,1
db 7,3,15,1,1
db 1,1,1,1,1
space db " ", 10
space_len equ $- space
section .bss
temp resb 5
section .text
global _start
_start:
mov r8, 0
mov r9, -6
print_output:
add r9, 6
mov rdx, 0
column_loop:
mov rax, [matr +r9]
test rax, 1
jnz next_element
add rdx, rax
next_element:
add r9, 5
loop column_loop
add rdx, '0'
mov [temp + r8], rdx
;mov rax, [matr + r9]
;mov rbx, [matr + 5 * r8 + 4 - r8]
;mul rbx
;add rax, '0'
;mov [temp + r8], rax
inc r8
cmp r8, 5
je _exit
jne print_output
_exit:
mov rsi, temp
mov rdx, 5
mov rax, write
mov rdi, stdout
syscall
mov rax, write
mov rdi, stdout
mov rsi, space
mov rdx, space_len
syscall
mov rax, exit
xor rdi, rdi
syscall
If you intresting what is io.asm is,
section .text ; ������� ����
IntToStr64:
push rdi
push rbx
push rdx
push rcx
push rsi
mov byte[rsi],0 ; �� ����� �����
cmp eax,0
jge .l1
neg eax
mov byte[rsi],'-'
.l1 mov byte[rsi+6],10
mov rdi,5
mov bx,10
.again: cwd ; ��������� ����� �� ��������
div bx ; ����� ��������� �� 10
add dl,30h ; �������� �� ������� ��� �����
mov [rsi+rdi],dl ; ����� ������ � ������
dec rdi ; ��������� ��������� ��
; ���������� �������
cmp ax, 0 ; ������������� ��� �����?
jne .again
mov rcx, 6
sub rcx, rdi ; ����� ����������+����
mov rax,rcx
inc rax ; ����� ����������+OA
inc rsi ; ���������� ����
push rsi
lea rsi,[rsi+rdi] ; ������ ����������
pop rdi
rep movsb
pop rsi
pop rcx
pop rdx
pop rbx
pop rdi
ret
StrToInt64:
push rdi
mov bh, '9'
mov bl, '0'
push rsi ; ��������� ����� �������� ������
cmp byte[rsi], '-'
jne .prod
inc rsi ; ���������� ����
.prod cld
xor di, di ; �������� ������� �����
.cycle: lodsb ; ��������� ������ (�����)
cmp al, 10 ; ���� 10, �� �� �����
je .Return
cmp al, bl ; ���������� � ����� ����
jb .Error ; "����" � ������
cmp al, bh ; ���������� � ����� ������
ja .Error ; "����" � ������
sub al, 30h ; �������� ����� �� �������
cbw ; ��������� �� �����
push ax ; ��������� � �����
mov ax, 10 ; ������� 10 � AX
mul di ; ��������, ��������� � DX:AX
pop di ; � DI � ��������� �����
add ax, di
mov di, ax ; � DI � ����������� �����
jmp .cycle
.Return: pop rsi
mov rbx, 0
cmp byte[rsi], '-'
jne .J
neg di
.J mov ax, di
cwde
jmp .R
.Error: pop rsi
mov rax, 0
mov rbx, 1
.R pop rdi
ret
Please don't close my question. I highly appreciate everyone's answers
I got a segment error, but I can't fix it.
I'm trying to get output as
2 8 8 0 24
2 8 8 0 24 0
2 8 8 0 24
These 'expected results' that you show us are not what the program would have to output. The correct result will be: 2 8 0 24 0
loop column_loop
The loop
instruction depends on the RCX register and you forgot to initialize it! Therefore your loop will have run for much too long, addressing memory beyond what is allowed and thus triggering Segmentation Error.
print_output: add r9, 6
This peculiar addition is another reason why you reach memory that is beyond the array. The inner loop already has raised R9 by 25 (5 x 5), and then you add another 6. What you could need is restoring R9 and then adding 1, possibly using push
and pop
. Alternatively, you could subtract 24 from R9. But by far the simplest solution would be to initialize R9 to the current value in R8.
matr db 2,2,3,4,1 db 5,1,5,8,1 db 9,6,1,12,1 db 7,3,15,1,1 db 1,1,1,1,1
Your matrix contains byte-sized data. You need to read the elements as such. Instead of mov rax, [matr +r9]
that reads 8 bytes, use movzx eax, byte [matr + r9]
. This will read a single byte and extend it into the full RAX register.
xor edi, edi ; Output offset [0,4]
OuterLoop:
mov esi, edi ; Input offset [0,24]
xor edx, edx
InnerLoop:
movzx eax, byte [matr + rsi]
test al, 1
jnz IsOdd
add edx, eax
IsOdd:
add esi, 5 ; To next row
cmp esi, 25 ; Is replacement for
jb InnerLoop ; the slow `LOOP`
add edx, '0' ; (*)
mov [temp + rdi], dl ; Only writing a single byte!
inc edi
cmp edi, 5
jb OuterLoop
(*) Expected output
280H0
The sum for the 4th column is 24. This cannot get displayed as a single digit via add edx, '0'
. I see that you already have a code IntToStr64 that could be useful for the conversion.