归并排序分段故障 NASM

Posted

技术标签:

【中文标题】归并排序分段故障 NASM【英文标题】:Merge sort segmentation Fault NASM 【发布时间】:2013-10-06 17:55:35 【问题描述】:

您好,我正在尝试在 linux 上的 nasm 中实现合并排序算法,但遇到分段错误,所以我在 konsole 中输入了这个“gdb mergesort core”,然后我得到了这个

"El núcleo se generó por «./mergesort».
 El programa terminó con la señal 11, Segmentation fault.
 #0  0x080481a5 in ?? ()
(gdb) bt
 #0  0x080481a5 in ?? ()
 #1  0x080481b1 in ?? ()
 #2  0x080480af in ?? ()"   

但我真的不明白如何处理它或发生分段错误的位置。谁能帮帮我?

对不起,这是我第一次在这里粘贴代码,所以我不知道如何按应有的方式缩进所有内容

NASM 中的代码如下:

BITS 32
extern printf
    section .data
    section .text
  global _start

  global main,
main:
  _start:

nop;
mov edi, sorted
mov esi, array
mov ecx, 10
rep movsd

push 10
push 0
push sorted
call mergesort
add esp, 12

push sorted
push 10
call print
add esp, 8
ret

merge:
push ebp
mov ebp, esp
push eax
push ecx
push edx
push edi
push esi



mov ecx, [ebp+20]
sub ecx, [ebp+12]

shl DWORD[ebp+12], 2
shl DWORD[ebp+16], 2
shl DWORD[ebp+20], 2

mov edx, temp       
mov edi, [ebp+8]    
add edi, [ebp+16]   



mov esi, [ebp+8]
add [ebp+12], esi
add [ebp+16], esi
add [ebp+20], esi
mov esi, [ebp+12]

.next:

cmp esi, [ebp+16]
jnz .second

cmp edi, [ebp+20]
jnz .first

jmp .end



.first:
cmp esi, [ebp+16]
jnz .second


mov eax, [edi]
mov [edx], eax
add edx, 4
add edi, 4
jmp .next

.second:
cmp edi, [ebp+20]
jnz .third


mov eax, [esi]
mov [edx], eax
add edx, 4
add esi, 4
jmp .next

.third:
mov eax, [esi]
cmp eax, [edi]
jnl .forth


mov [edx], eax
add edx, 4
add esi, 4
jmp .next

.forth:
mov eax, [edi]
mov [edx], eax
add edi, 4
add edx, 4
jmp .next
.end:



mov esi, temp
mov edi, [ebp+12]
rep movsd


pop esi
pop edi
pop edx
pop ecx
pop eax
mov esp, ebp
pop ebp
ret

mergesort:
push ebp
mov ebp, esp
push eax

mov eax, DWORD[ebp+16]  
sub eax, [ebp+12]   
cmp eax, 2
JL .end
    push edx
    push ebx
        xor edx, edx
        mov ebx, 2
        div ebx
    pop ebx
    pop edx
    add eax, [ebp+12]   


    push eax        
    push DWORD[ebp+12]  
    push DWORD[ebp+8]   
    call mergesort
    add esp, 12

    push DWORD[ebp+16]  
    push eax        
    push DWORD[ebp+8]   
    call mergesort
    add esp, 12

    push DWORD[ebp+16]  
    push eax        
    push DWORD[ebp+12]  
    push DWORD[ebp+8]   
    call merge
    add esp, 16
.end:
pop eax
mov esp, ebp
pop ebp
ret


print:
push ebp    
mov ebp, esp
push ecx
push edx

mov edx, [ebp+12]
mov ecx, [ebp+8]

.args:
    push ecx
    push edx
    push DWORD[edx]
    push format
    call print
    add esp, 8
    pop edx
    pop ecx
    add edx, 4
LOOP .args

push endl
call print
add esp, 4

pop edx     
pop ecx     
mov esp, ebp    
pop ebp     
ret     

format:
db  ' %2d', 0
endl:
db  10, 0

array:
dd  10, 9, 8, 4, 5, 6, 7, 3, 2, 1


section .bss
sorted:
resd    10
temp:
resd    10

【问题讨论】:

【参考方案1】:

首先,为什么code 部分中定义了数据? 这个:

format:
db  ' %2d', 0
endl:
db  10, 0

array:
dd  10, 9, 8, 4, 5, 6, 7, 3, 2, 1

应该在您的.data 部分。

通过将-F stabs 添加到 NASM 的命令行(在 Linux 中)将调试符号添加到您的目标文件我不确定 Windows 的选项。 nasm -f elf -F stabs $(APP).asm

这将在 gdb 回溯中显示您的函数名称。

问题似乎出在您的print 函数中,请仔细查看!您正在递归调用它。

print:
    push    ebp    
    mov     ebp, esp
    push    ecx
    push    edx

    mov edx, [ebp+12]
    mov ecx, [ebp+8]

.args:
    push    ecx
    push    edx

    push    DWORD[edx]
    push    format
    call    print ; <<<<<<<<<<
    add     esp, 8

    pop     edx
    pop     ecx

    add     edx, 4
    LOOP    .args

    push    endl
    call    print ; <<<<<<<<<<
    add     esp, 4

    pop     edx     
    pop     ecx     
    mov     esp, ebp    
    pop     ebp     
    ret     

我想你的意思是打电话给printf

print:
    push    ebp    
    mov     ebp, esp
    push    ecx
    push    edx

    mov     edx, [ebp+12]
    mov     ecx, [ebp+8]

.args:
    push    ecx
    push    edx

    push    DWORD[edx]
    push    format
    call    printf
    add     esp, 8

    pop     edx
    pop     ecx

    add     edx, 4
    LOOP    .args

    push    endl
    call    printf
    add     esp, 4

    pop     edx     
    pop     ecx     
    mov     esp, ebp    
    pop     ebp     
    ret  

看到区别了吗?解决这个问题,它似乎打印正确!

【讨论】:

嗨,感谢 print 和 printf 的问题,我ve already fixed it, but now Im 得到一个未定义的 printf 引用,那是什么?? 看起来您的代码来自 github.com/hugopeixoto/mergesort/blob/master/assembly/…,您是否使用该代码第 2 行和第 3 行的命令进行了汇编和链接?

以上是关于归并排序分段故障 NASM的主要内容,如果未能解决你的问题,请参考以下文章

❤️数据结构入门❤️(4 - 4)- 归并排序

十大经典排序之:归并排序 |桶排序

常见排序算法之归并排序——归并排序

归并排序

归并排序(递归非递归以及自然归并排序)算法总结

排序算法——归并排序