装配矩阵比较分割故障

时间:2011-11-07 18:54:44

标签: assembly x86

我的目标是以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

1 个答案:

答案 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)