Masm32 SDK description, downloads and other helpful links

Main Menu

Problem with QSORT call

Started by mitchi, January 12, 2013, 06:45:03 AM

Previous topic - Next topic


I am rewriting my C Kruskal algorithm in Assembly language. For fun and learning purposes  :icon_mrgreen:
I am running into a problem with my QSORT call here... my program goes into qsort, never to return.

I spent a lot of time debugging and I don't see where my problem is. I think my memory is ok. I used both a static array and dynamic memory and I got the same results.
It calls compare once, it loads the proper values, compares them well. Then it goes back into QSORT and boom!

The code is here :


Try to not destroy content of register ebx in the cmp proc!


It works... !!!!!
I'm so happy.
So basically I have to save the contents of certain registers? Which one do I have to save between calls?


EAX, ECX, EDX can be trashed
EBX, ESI, EDI, EBP must be preserved
if you set the direction flag, you should leave it cleared before calling an API function
anybodies guess as to whether FPU or XMM registers are preserved in API calls - lol



There are times when I feel like a voice crying in the wilderness, after having published technical data to support the Intel ABI (what registers etc ...) over and over and over (yawn) and over and over and over (ZZZZZzzzzzzz_______ .......) again and again and again we still fail to connect that if you want to write reliable code that works, you preserve the right registers in and out of an algorithm.    :biggrin:  :skrewy:


i made that post with a single stroke of a hot-key   :lol:


Quote from: dedndave on January 13, 2013, 02:09:51 PM
i made that post with a single stroke of a hot-key   :lol:
Smart :)


Hi mitchi,

Quote from: mitchi on January 14, 2013, 07:47:05 PM
Smart :)

Dave is smart all the time. But joke apart: you should read the Application Binary Interface (ABI). You can find a lot of remarks to that in Agner Fog's manuals:

Good luck!

You have to know the facts before you can distort them.


Hi mitchi,

A quick example :

.model flat,stdcall
option casemap:none

include     \masm32\include\
include     \masm32\include\
include     \masm32\include\

includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\msvcrt.lib




str1    db 'Orange',0
str2    db 'Cherry',0
str3    db 'Strawberry',0
str4    db 'Apple',0
str5    db 'Fig',0
str6    db 'Apricot',0
str7    db 'Pear',0
str8    db 'Peach',0

StrTabl dd str1,str2,str3,str4,str5,str6,str7,str8

msg     db 'List of fruits in alphabetical order',13,10
        db '====================================',13,10,13,10,0

format1 db '%s',13,10,0



    invoke  crt_qsort,ADDR StrTabl,NUMB_OF_ELEMENTS,\
            SIZEOF DWORD,ADDR CompareProc

    call    PrintArray

    invoke  ExitProcess,0

CompareProc PROC C USES esi edi arg1:DWORD,arg2:DWORD

    mov     ecx,arg1
    mov     edx,arg2

    mov     esi,DWORD PTR [ecx]
    mov     edi,DWORD PTR [edx]

    mov     ecx,1
    mov     edx,-1
    add     edx,ecx
    movzx   eax,BYTE PTR [esi+edx]
    test    eax,eax
    jz      _exit
    cmp     al,BYTE PTR [edi+edx]
    je      @b

    sbb     eax,eax
    sbb     eax,-1

; To sort an array in decreasing order, reverse the sense of
; greater than and less than in the comparison function :
;   neg     eax



CompareProc ENDP

PrintArray  PROC uses esi ebx

    mov     ebx,NUMB_OF_ELEMENTS
    mov     esi,OFFSET StrTabl

    invoke  crt_printf,ADDR msg
    invoke  crt_printf,ADDR format1,DWORD PTR [esi]
    add     esi,4
    dec     ebx
    jnz     @b

PrintArray ENDP

END start