x86汇编数组索引访问报错:invalid operand type问题求助
解决NASM编译错误:
invalid operand type 及汇编代码修正 错误原因
你遇到的mov ecx, array+r8d报错,是因为NASM不支持将符号地址(如array)与32位寄存器直接相加作为mov的源操作数。x86汇编中,动态计算内存地址需要先将基地址加载到寄存器,再通过加法偏移得到目标地址。
同时你的代码还有两处逻辑错误,和原JavaScript功能不符:
.data段中array的定义错误:原JS是包含两个字符串的数组,你直接将"ola"和"mundo"拼接成了一个连续字符串,没有区分元素。write系统调用的长度参数错误:你每次传递arrayLength,会输出整个连续内存的内容,而不是单个数组元素。
修正后的完整代码
global main section .data newline db 0xa ; 定义两个字符串元素,以0结尾方便计算长度 str1 db "ola", 0 str2 db "mundo", 0 ; 定义指针数组,存储每个字符串的地址(32位指针,适配int 0x80的32位调用) array dd str1, str2 ; 计算数组元素个数:总字节数除以每个指针的字节数(4字节) arrayLength equ ($ - array) / 4 section .text main: mov ecx, 0 ; 初始化循环索引i=0 beginLoop: cmp ecx, arrayLength je exit ; 当i >= arrayLength时退出循环 push ecx ; 保存循环索引 ; 1. 获取当前元素的地址:array[i] mov eax, [array + ecx*4] ; 每个指针占4字节,所以偏移是ecx*4 ; 2. 计算当前字符串的长度(遍历到0终止符) mov ebx, eax mov edx, 0 count_len: cmp byte [ebx], 0 je count_done inc ebx inc edx jmp count_len count_done: ; 3. 调用write系统输出字符串 mov eax, 4 mov ebx, 1 mov ecx, eax ; eax存储当前字符串的地址 int 0x80 ; 4. 输出换行符 mov eax, 4 mov ebx, 1 mov ecx, newline mov edx, 1 int 0x80 pop ecx ; 恢复循环索引 inc ecx ; i++ jmp beginLoop exit: ; 调用exit系统调用退出程序 mov eax, 1 mov ebx, 0 int 0x80
关键修正点说明
- 地址计算修正:
用mov eax, [array + ecx*4]获取数组第i个元素的地址,因为数组存储的是32位指针,每个指针占4字节,所以偏移量是ecx*4。 - 数组结构修正:
将原连续字符串改为指针数组array dd str1, str2,每个元素指向对应的字符串,符合原JS数组的结构。 - 字符串长度计算:
新增count_len循环,遍历字符串到终止符0,计算每个元素的实际长度,确保输出内容正确。 - 系统调用参数修正:
输出字符串时,edx传递的是当前字符串的长度,而非整个数组的长度。
编译运行命令
nasm -f elf32 -o array.o array.asm ; 适配int 0x80的32位调用,编译为elf32格式 ld -m elf_i386 -o array array.o ; 链接时指定32位目标 ./array
内容的提问来源于stack exchange,提问作者spyblock
相关产品推荐
相关产品推荐

