【问题标题】:Insertion sort not working, 32bit assembly插入排序不起作用,32 位汇编
【发布时间】:2014-12-28 21:35:04
【问题描述】:

我正在尝试使用 NASM 在 linux 的 32 位程序集中实现插入排序,但在运行过程中出现分段错误(更不用说由于某种原因“printf”打印随机垃圾值,我不完全确定为什么), 这里是 代码: 节.rodata MSG: DB "欢迎来到 sortMe,请给我排序",10,0 S1: 数据库 "%d",10,0 ; 10 = '\n' , 0 = '\0'

section .data

array   DD 5,1,7,3,4,9,12,8,10,2,6,11   ; unsorted array
len DB 12   

section .text
    align 16
    global main
    extern printf

main:
    push MSG    ; print welcome message
    call printf
    add esp,4   ; clean the stack 

    call printArray ;print the unsorted array

    ;parameters
    ;push len
    ;push array
    mov eax, len
    mov ebx, array
    push eax
    push ebx

    call myInsertionSort

    call printArray ; print the sorted one

    mov eax, 1  ;exit system call
    int 0x80

printArray:
    push ebp    ;save old frame pointer
    mov ebp,esp ;create new frame on stack
    pushad      ;save registers

    mov eax,0
    mov ebx,0
    mov edi,0

    mov esi,0   ;array index
    mov bl, byte [len]
    add edi,ebx ; edi = array size

print_loop:
    cmp esi,edi
    je print_end
    push dword [array+esi*4]
    push S1
    call printf
    add esp, 8  ;clean the stack
    inc esi
    jmp  print_loop
print_end:
    popa        ;restore registers
    mov esp,ebp ;clean the stack frame
    pop ebp     ;return to old stack frame
    ret

myInsertionSort:
    push ebp
    mov ebp, esp
    push ebx
    push esi
    push edi
    mov ecx, [ebp+12]
    movzx ecx, byte [ecx]   ;put len in ecx, our loop variable
    mov eax, 0
    mov ebx, 0
    mov esi, [ebp+8] ; the array
    loop loop_1
    loop_1:
        cmp ecx, 0 ; if we're done
        je done_1 ; then done with loop
        mov edx, ecx
        push ecx ; we save len, because loop command decrements ecx
        sub edx, ecx
        mov ecx, [esi+4*edx] ;;;;;; ecx now array[i] ? how do I access array[i] in a similar manner?
        mov ebx, eax
        shr ebx, 2 ; number of times for inner loop
        loop_2:
            cmp ebx, 0 ; we don't use loop to not affect ecx so we use ebx and compare it manually with 0
            jl done_2
            cmp [esi+ebx], ecx ;we see if array[ebx] os ecx so we can exit the loop
            jle done_2
            lea edx, [esi+ebx]
            push dword [edx] ; pushing our array[ebx]
            add edx, 4
            pop dword [edx] ; popping the last one
            dec ebx ; decrementing the loop iterator
            jmp loop_2 ; looping again
        done_2:
            mov [esi+ebx+1], ecx
            inc eax ; incrementing iterator
            pop ecx ; len of array to compare now to eax and see if we're done
            jmp loop_1
    done_1:
        pop edi
        pop esi
        pop ebx
        pop ebp ; we pop them in opposite to how we pushed
        ret

关于 printf 的事情,我很肯定我应该以相反的方式推送参数(首先是 S1,然后是整数,所以它是从左到右的,就像我们在 C 中所说的那样),如果我切换它们,当我遇到分段错误时,根本没有打印任何内容。我不知道该怎么做,它将这些打印为输出:

welcome to sortMe, please sort me
5
16777216
65536
256
1
117440512
458752
1792
7
50331648
196608
768

【问题讨论】:

    标签: linux assembly insertion-sort


    【解决方案1】:
    mov ecx, [ebp+12]   ;put len in ecx, our loop variab  
    

    这只会将 LEN 的地址移动到 ECX 中,而不是它的值!您需要添加movzx ecx, byte [ecx]

    您还需要定义 LEN=48

    loop loop_1  
    

    LOOP 在这里有什么奇怪的用途?
    您在多个场合混合了字节和双字。您需要重新编写代码。体育

    dec ebx ; ebx is now number of times we should go through inner loop  
    

    应该变成

    shr ebx,2
    

    这是不正确的,因为您需要的是地址而不是值。将 MOV 更改为 LEA。

    jle done_2
    mov edx, [esi+ebx]
    

    也许您可以在原始问题中将修改后的代码作为 EDIT 发布。

    【讨论】:

    • 谢谢,没有核心转储,但它仍然无法正常工作。
    【解决方案2】:

    您编辑的代码并未解决 user3144770 发出的所有问题!

    printf 的参数是正确的,但是您的 printArray 例程存在一些其他问题。

    1. 由于 ESI 是双字数组中的索引,因此您需要对其进行扩展!

      push dword [array+esi*4]

    2. 你确定pusha 会保存 32 位吗?也许你最好使用pushad

    ps 如果您决定重新编写代码并发布编辑,请在现有帖子的最后一行之后添加重新编写的代码。这样,原始问题将继续对第一次查看它的人有意义!

    【讨论】:

    • 哦,谢谢,但仍然无法正常工作,您在哪里可以看到另一个问题?我更正了你指出的内容。我真的很沮丧,作业已经到期了,但我还是想从错误中吸取教训:P
    • 我认为这是因为我尝试获取数组 [i] 的循环中的一行,我怀疑我正在做与我应该做的事情相似的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多