Author Topic: Please help me, my program doesnt work, i dont know why  (Read 3327 times)

Offline Pora

  • Jr. Member
  • *
  • Posts: 3
Please help me, my program doesnt work, i dont know why
« on: February 11, 2011, 10:33:12 AM »
I write c program that sort array. In that program i call function that i wrote in asm, it must
sort and then write array on the screen
I asembly program, no errors, than link with main.c use this commands
nasm -f win32 sort.asm
h:\mingw\bin\gcc -o sort.exe main.c sort.obj asm_io.obj
it is ok when i delete part of code where i sort numbers, when i back that code,notting happens, empty screen
this is main.c
Code: [Select]
#include <stdio.h>
/* prototip za asemblersku rutinu */
void sort(int*);
int main()
{
   int a[1000];
int i;
   for(i=0;i<1000;i++)
   a[i]=i;
sort(a);
    return 0;
}
this is sort.asm
Code: [Select]
%include "asm_io.inc"
segment .text
global _sort
_sort:
enter 0,0 ;
push ebx
push esi
push edi
mov ecx,1000
mov ebx,0
cld
mov esi,[ebp+8]
mov edi,[ebp+8]
sub esi,4

pomjerajprvi:
lodsd
inc ebx
cmp ebx,1000
je dalje
sub ecx,ebx

prviiostali:
scasd
jl nijeispunjeno
mov edx,[edi]
xchg edx,[esi]
mov [edi],edx
nijeispunjeno:
loop prviiostali
mov ecx,1000
jmp pomjerajprvi

dalje:
mov ecx,1000
mov ebx,[ebp+8]
mov esi,0
ispis:
cmp esi,4000
je kraj
mov eax,[ebx]
call print_int
add ebx,4
add esi,4
mov eax,32
call print_char
loop ispis
kraj:
pop edi
pop esi
pop ebx
pop ebp
leave
ret

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2379
  • Country: us
Re: Please help me, my program doesnt work, i dont know why
« Reply #1 on: February 11, 2011, 04:29:18 PM »
"Your program doesn't work because something you believe to be true is not true." That's a "general rule" I picked up from a web page about debugging Linux programs, but it applies in Windows, too. Now, you just have to figure out what that is! :)

I couldn't spot anything, at first, so I assembled/compiled it for Linux. Worse than "no output", it segfaulted! Took me a while to figure out why - this is a little subtle... "scasd", of course, adds 4 to edi. No problem through the first loop, but after falling through and going back to do the next item in the array, edi doesn't get reset and just keeps going and going like the Energizer Bunny! :)

First, I should observe that your array, the way you initialize it in the .c program, is sorted anyway - just a "nop" would work. To prove to myself that this was actually doing something, I modified your .c program to initialize the array from 999 down to 0, instead of 0 to 999. (a[ i ] = 999 - i) Random probably would have been even better. This isn't a "bug" or a "problem", I just did it to "prove to myself"...

After fixing the "runaway scasd", I was getting a "scrambled" array! This is perhaps even subtler! Where you exchange [esi] and [edi]... both registers have been incremented by 4 by the "lodsd" and "scasd", so you're swapping the "next two" integers, instead of the two you just compared! Took me a second cup of coffee to figure that one out! Changing to [esi - 4] and [edi - 4] in that section fixed it...

You do:
Code: [Select]
mov esi,[ebp+8]
mov edi,[ebp+8]
sub esi,4

I don't like that. The first "lodsd" is getting the dword before the start of your array - not what you really want. I like "add edi, 4" better, but I realized (after the second cup of coffee) that esi, after the "lodsd", is where we want edi to start for the first "scasd", so I did:

Code: [Select]
%include "asm_io.inc"
segment .text
;global _sort
;_sort:
global sort  ; Linux doesn't use the underscore - change back, for Windows
sort:
    enter 0,0 ;
    push ebx
    push esi
    push edi

    mov ecx,1000
    mov ebx,0
    cld
    mov esi,[ebp+8]

pomjerajprvi:
    lodsd
    inc ebx
    cmp ebx,1000
    je dalje
    sub ecx,ebx
    mov edi, esi ; <-

prviiostali:
    scasd
    jle nijeispunjeno ; "jl" swaps if they're equal - pointless!
    mov edx,[edi - 4] ; <-
    xchg edx,[esi - 4] ; <-
    mov [edi - 4],edx ; <-
nijeispunjeno:
...

With those changes, it "works for me".

Not a very optimal sort routine. Could perhaps be improved by passing the size of the array as a second parameter, instead of hard-coding 1000. Might be better to do "sort array" and "print array" as two separate routines instead of the combined "sort and print". But with those minor changes, it "works". Good job!

Best,
Frank


Offline Pora

  • Jr. Member
  • *
  • Posts: 3
Re: Please help me, my program doesnt work, i dont know why
« Reply #2 on: February 11, 2011, 11:27:51 PM »
I have learned NASM on college for few weeks, i try to do somethig usefull (for pratice)and to compare same program in c++ and in asm, because compiler do same thing in background
My goal was to sort in decreasing order (because i fill array in other way), same thing ,condision < or >
I know that this is not optimale code, i know many other algoritams, but it is hard to do in asm
I see on internet, people mostly use asm to develope some drivers or something like that on low level
or to call system functions for drawing windows (GUI)
This is to hard for me, i want to write part of fast code, if is it posible for me because i am not good in asm
surely compiler is better
I read art of assembly, but it is for masm

sorry for my english, i know that are many mistakes
« Last Edit: February 12, 2011, 12:18:46 AM by Pora »

Offline Pora

  • Jr. Member
  • *
  • Posts: 3
Re: Please help me, my program doesnt work, i dont know why
« Reply #3 on: February 12, 2011, 12:14:32 AM »
Big problem is that many things are do in c++, i know that c++ give some strange name for functions because he allow that two funcions have same name but different parameters
and it is hard to realize object oriented programing

Offline Rob Neff

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 430
  • Country: us
Re: Please help me, my program doesnt work, i dont know why
« Reply #4 on: February 12, 2011, 12:15:21 AM »

Just stick with it.  To borrow an old quote: Rome wasn't built in a day, my friend.... ;)