无法访问程序集 x86 中的数组索引

问题描述 投票:0回答:1

我试图在汇编中做相当于:

const array = ["ola", "mundo"]

for (i = 0; i < array.length; i++){
  console.log(array[i])
}
global main

section .data
        newline db 0xa
        array db "ola","mundo"
        arrayLength equ $ - array

section .text

main:
        mov ecx, 0

beginLoop:
        cmp ecx, arrayLength
        je exit

        mov r8d, ecx
        push ecx

        mov eax, 4
        mov ebx, 1
        mov ecx, array+r8d
        mov edx, arrayLength
        int 0x80

        mov eax, 4
        mov ebx, 1
        mov ecx, newline
        mov edx, 1
        int 0x80

        pop ecx
        inc ecx
        jmp beginLoop

exit:
        mov eax, 1
        mov ebx, 0
        int 0x80

但是当我编译时,当我使用寄存器 r8d 访问索引时,它会抛出错误:

nasm -f elf64 -o array.o array.asm array.asm:22: 错误:操作数类型无效

第 22 行是

mov ecx, array+r8d

arrays assembly x86
1个回答
0
投票

但是当我编译时,当我使用寄存器 r8d 访问索引时,它会抛出错误:

NASM 无法通过

mov ecx, array+r8d
加载地址,因为
r8d
组件不是立即值,它是一个寄存器,其值仅在运行时可用。您可以使用 LEA 并写下
lea rcx, [array + r8]
。在寻址模式下使用整个 qword 寄存器。

array db "ola","mundo"

您的程序无法知道一个数组元素在哪里结束以及下一个数组元素在哪里开始。您的程序“看到”的所有内容都是一个 8 个字符的字符串“olamundo”。
一种解决方案可能是使用零终止,如

array db "ola", 0, "mundo", 0
中所示。另一种解决方案可以使用
array db "ola     ", "mundo   "
中的填充符来处理相同大小的字符串。另一种解决方案可以是在数组元素前添加一个包含长度指示的字节:

array db 3, "ola", 5, "mundo"
arrayLength equ $ - array

初稿:

main:
  mov   rsi, array
  mov   ebx, 1
.Loop:
  movzx edx, byte [rsi]
  lea   rcx, [rsi + 1]
  mov   eax, 4
  int   0x80
  lea   rsi, [rcx + rdx]
  mov   edx, 1
  mov   rcx, newline
  mov   eax, 4
  int   0x80
  cmp   rsi, array + arrayLength
  jb    .Loop
© www.soinside.com 2019 - 2024. All rights reserved.