Author Topic: Problem with QSORT call  (Read 7362 times)

mitchi

  • Guest
Problem with QSORT call
« on: January 12, 2013, 06:45:03 AM »
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 :
https://github.com/mitchi/Kruskal-ASM/blob/master/kruskal.asm

https://github.com/mitchi/Kruskal-ASM

japheth

  • Guest
Re: Problem with QSORT call
« Reply #1 on: January 12, 2013, 07:12:22 AM »

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

mitchi

  • Guest
Re: Problem with QSORT call
« Reply #2 on: January 12, 2013, 07:31:16 AM »
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?

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: Problem with QSORT call
« Reply #3 on: January 12, 2013, 07:46:50 AM »
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

mitchi

  • Guest
Re: Problem with QSORT call
« Reply #4 on: January 12, 2013, 07:52:47 AM »
thanks

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 9988
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Problem with QSORT call
« Reply #5 on: January 13, 2013, 02:07:45 PM »
 :biggrin:

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.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

dedndave

  • Member
  • *****
  • Posts: 8828
  • Still using Abacus 2.0
    • DednDave
Re: Problem with QSORT call
« Reply #6 on: January 13, 2013, 02:09:51 PM »
i made that post with a single stroke of a hot-key   :lol:

mitchi

  • Guest
Re: Problem with QSORT call
« Reply #7 on: January 14, 2013, 07:47:05 PM »
i made that post with a single stroke of a hot-key   :lol:
Smart :)

Gunther

  • Member
  • *****
  • Posts: 4115
  • Forgive your enemies, but never forget their names
Re: Problem with QSORT call
« Reply #8 on: January 15, 2013, 03:26:29 AM »
Hi mitchi,

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: http://agner.org/optimize/

Good luck!

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

Vortex

  • Member
  • *****
  • Posts: 2716
Re: Problem with QSORT call
« Reply #9 on: January 15, 2013, 05:06:10 AM »
Hi mitchi,

A quick example :

Code: [Select]
.386
.model flat,stdcall
option casemap:none

include     \masm32\include\windows.inc
include     \masm32\include\kernel32.inc
include     \masm32\include\msvcrt.inc

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

CompareProc PROTO C :DWORD,:DWORD
strcmpX     PROTO :DWORD,:DWORD

NUMB_OF_ELEMENTS equ 8


.data

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


.code

start:

    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

_exit:

    ret

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
    ret

PrintArray ENDP


END start