我试图在汇编中做相当于:
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
但是当我编译时,当我使用寄存器 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