我的目标是以5x5矩阵加载值并比较每个值并打印出最大的数字。
运行调试器后,我得到:
0x080480bb <+0>: mov esi,DWORD PTR [eax+edi*1]
0x080480be <+3>: jmp 0x804809d <loop>
segment .data
matrix db 1,62,3,44,35, \
61,52,43,45,55, \
17,23,37,74,65, \
13,12,93,94,95, \
31,21,13,14,25
segment .bss
holder resb 4
counter resb 4
segment .text
global _start
_start:
mov eax, matrix
call big
big:
mov esi, holder
mov edi, counter
mov edi, 0
jmp switch
loop:
inc edi
cmp esi, [eax + edi]
jg switch
cmp edi, 25
jle loop
mov eax, [esi]
sub eax, '0'
mov eax, 4
mov ebx, 1
mov ecx, esi
mov edx, 4
int 0x80
switch:
mov esi, [eax + edi]
jmp loop
exit:
mov eax, 1
xor ebx, ebx
int 0x80
答案 0 :(得分:1)
我可以在你的代码中看到一些问题。这是第一个:
cmp edi, 25
jle loop
mov eax, [esi] <--
sub eax, '0'
mov eax, 4
此时,您已经检查了整个矩阵,并希望记下找到的最大值(已经在esi中),因此您无需取消引用即可获取它。此外,您应该<0>为0到9之间的数字添加'0',因此转换也是错误的。并且,最后一件事,在转换之后,你将覆盖eax中的价值,因此失去了它 真正的分段错误,如此,发生在这里,
mov esi, [eax + edi] <--
jmp loop
写完结果后。问题是ecx应该包含一个指向零终止字符串的指针。而不是那样,你输入你想要写的数字,这是未定义的行为(这意味着一切都可能发生)。现在,eax保持write的返回值,所以我的猜测是发生错误,eax现在包含-1,导致seg。故障。
一个简单的解决方法是在写入值后添加一个jmp退出。
而且,最后但并非最不重要的,(并且正如@ user786653所说),“没有正确处理你的字节大小的数据”。那是什么意思?基本上,你的矩阵是一个字节数组,但每次从内存中读取时,你会得到4个字节。最简单的解决方案是将矩阵声明为双字数组(dd或dword代替db)并将偏移量乘以4(例如:mov eax,[ebx + ecx * 4])。
来吧,别担心!装配是一个难以驾驭的野兽;) 修改强>
找到最大数字的部分是正确的。你只需修复“输出”部分和我前面说过的寻址内容。在我看来,如果你使用十六进制数字将数字转换为可打印的字符串会更容易(你可以通过向左移动n个位置乘以2 ^ n - &gt; shl eax,5 = eax * = 32)