【发布时间】:2015-05-05 15:37:54
【问题描述】:
我一直在尝试打印数组的元素。我有这段代码,它对数组的所有元素求和并打印结果,我尝试以多种方式进行编辑,但没有运气。
这是我在网上找到的代码:
section .text
global _start ;must be declared for linker (ld)
_start:
mov eax,3 ;number bytes to be summed
mov ebx,0 ;EBX will store the sum
mov ecx, x ;ECX will point to the current element to be summed
top: add ebx, [ecx]
add ecx,1 ;move pointer to next element
dec eax ;decrement counter
jnz top ;if counter not 0, then loop again
done:
add ebx, '0'
mov [sum], ebx ;done, store result in "sum"
display:
mov edx,1 ;message length
mov ecx, sum ;message to write
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax, 1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
global x
x:
db 2
db 4
db 3
sum:
db 0
这是我没有运气的编辑方法(我尝试了很多其他的东西)。这会打印第一个元素 '2' 并给出 Segmentation fault 错误。
编辑:这是工作代码,谢谢大家,谢谢 ElderBug! :)
_start:
mov esi,3 ;number bytes to be traversed
mov edi, x ;EDI will point to the current element to be summed
mov eax, 0 ;eax will hold the text to print
top:
mov eax, [edi] ;store current element
add edi,1 ;move pointer to next element
add eax, '0' ;do the conversion
mov [toprint], eax
mov ecx, toprint ;message to write
mov edx,1 ;message length
mov ebx, 1 ;file descriptor (stdout)
mov eax, 4 ;system call number (sys_write)
int 0x80 ;call kernel
dec esi ;decrement counter
jnz top ;if counter not 0, then loop again
mov eax, 1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
global x
x:
db 2
db 4
db 3
toprint:
dw 'x'
我知道“int 0x80”样式 4 表示写入,第一个参数存储在 ebx 中,第二个存储在 ecx 中,第三个存储在 edx 中。但想不通。
【问题讨论】:
-
您也可以使用
esi和edi。如果您真的用完了寄存器,您可以将它们保存在堆栈中,例如通过push/pop或适当的局部变量。 PS:你已经删除了将数字转换为文本的部分,所以你不会喜欢你得到的东西;) -
原码正确吗?
mov ebx,0 ;EBX will store the sum然后mov [sum], [ecx] ;done, store result in sum -
ecx 参数必须是指向字符的指针。您的信息必须在内存中。
-
@vandale 毫无疑问。
mov [sum], [ecx]在 x86 中甚至无效。正确的行是mov [sum], ebx。 -
不,更糟糕的是,它会尝试加载地址 esi 处的内容,但 esi 不包含地址。该消息确实需要在内存中。那也可能在堆栈上。您可以选择逐个打印字符,也可以同时打印所有字符。