-1

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

OBay
  • 13
  • 3
  • That can not be your `io.asm` since it has `_start` in it which woudl conflict with your main file and should not even assemble. Please make sure you post the code you are actually using. In any case, your main file seems to be self contained, it doesn't reference anything external so it doesn't need `io.asm` whatever it may be. Also, use a debugger to at least find the crashing instruction. – Jester May 30 '23 at 13:33
  • 1
    Anyway, `test rax, 1` doesn't do what you think it does, you want `cmp`. Same goes for `loop`, that requires a count in `rcx` that you did not set up. You have an array of bytes, but process 8 bytes every time. – Jester May 30 '23 at 13:36
  • Hi I edited Sorry – OBay May 30 '23 at 13:37
  • 1
    test used for check number even or not – OBay May 30 '23 at 13:41
  • 1
    Well okay, it is fine for that purpose. I thought you wanted to check the `1,1,1,1,1` at the end :) – Jester May 30 '23 at 13:46
  • You were correctly accessing single bytes from your matrix last time you posted about this (https://stackoverflow.com/questions/76351068/error-while-on-matrix-each-colum-even-numbers-sum-print), and I even commented that you could `movzx eax, byte [mat + r9]` ([How to load a single byte from address in assembly](https://stackoverflow.com/q/20727379)). But you ignored that and are loading 8 bytes at a time with `mov rax, [matr +r9]`, overlapping the next 7 bytes after the one you want. – Peter Cordes May 30 '23 at 18:52
  • What do you mean? Are there any loop problem. I change it But didn't make output which I was expect – OBay May 31 '23 at 05:30
  • Anyway just delete this stupid question. I don't understand why people downgrade my question. I saw there are thousand stupid questions than mine here. I know this is not non of there business and they do this just for free. But why anyone can't just put code in there system and try. This is just simple task who have good knowledge with assembly. I almost wasted 1 week for this questions and got depression. At least can you guys stop downgrading. That's suck. – OBay May 31 '23 at 07:28
  • 1
    As I said, you need a counter in `rcx` for `loop` to work. – Jester May 31 '23 at 14:54
  • @OBay - If you're replying to people, make sure to @ notify them. Other people don't get notified by default since this isn't their post. For your loop, since there's nothing after `temp resb 5` it happens to work to do overlapping 8-byte stores, instead of 1-byte stores. And checking the low bit + adding both work even with garbage in the high bytes of the register. But if you were single-stepping with a debugger you'd see big values in your registers. You definitely should be using a debugger, like GDB or LLDB, or a GUI front-end for them; that will save tons of time in the long run. – Peter Cordes May 31 '23 at 15:23

1 Answers1

0
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.

My suggestion for the nested loop

  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.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76