assembly Nasm 64程序集列的偶数总数显示在阵列上

8zzbczxx  于 2023-06-06  发布在  其他
关注(0)|答案(1)|浏览(72)

我有矩阵5,5.我试图打印数组(5)中每列的偶数总数。有人能帮忙吗?我得到了一个片段错误。请不要告诉我开始另一种语言。我已经试了三天了。但我还是找不到错误。拜托
我期待的答案是
2880240
这是我的代码:

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

如果你对什么是io.asm感兴趣,

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

请不要结束我的问题。我非常感谢大家的回答
我得到了一个段错误,但我不能修复它。
我试图得到输出为
288024

kxxlusnw

kxxlusnw1#

2 8 8 0 24 0
2 8 8 0 24

你向我们展示的这些“预期结果”并不是程序必须输出的结果。正确的结果将是:2 8 0 24 0

loop column_loop

loop指令依赖于RCX寄存器,而您忘记初始化它!因此,您的循环将运行太长时间,寻址内存超出允许的范围,从而触发分段错误。

print_output:
  add r9, 6

这种特殊的添加是获得超出数组的内存的另一个原因。内部循环已经将R9提升了25(5 x 5),然后再增加6。您可能需要恢复R9,然后添加1,可能使用pushpop。或者,您可以从R9中减去24。但到目前为止,最简单的解决方案是将R9初始化为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

您的矩阵包含字节大小的数据。你需要这样阅读这些元素。使用movzx eax, byte [matr + r9],而不是读取8字节的mov rax, [matr +r9]。这将读取单个字节并将其扩展到整个RAX寄存器。

我对嵌套循环的建议

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

(*)预期产出

280H0

第四列的总和是24。这不能通过add edx, '0'显示为个位数。我看到您已经有了一个代码 * IntToStr 64 *,可能对转换很有用。

相关问题