Am trying to create simple code that asks the user to enter a number and prints "hello world" as many times as specified by the number entered by the user.it seems am doing it all wrong.here is the code am using NASM.


segment .data
ifmt db "%d",0
fmte db "%d  %s",0
fmt db "%s",0
msgo db "hello world!",10,0
msg db "How many times would you like to print? ",10,0


segment .bss

segment .text

global _func
extern _printf,_scanf
_func:
push ebp
mov ebp,esp
pusha

push msg
push fmt
      call _printf

      xor edx,edx
lea edx,
push edx
push ifmt
call _scanf

      mov ebx,dword
      mov eax,1
      xor ecx,ecx
   
label:
  push msgo
  push ecx
  push fmte
  call _printf
  add esp,12

  inc eax
  cmp eax,ebx
  jle label


add esp,16

popa
mov esp,ebp
pop ebp
ret


Posted on 2010-11-23 12:58:24 by ashken
Quite a few things at first glance:

1.) Do not use eax to maintain your count as this will be destroyed by just about any call made and is (almost) always used as a return variable.
2.) Save the register containing your loop count ( prefereably ecx ) BEFORE setting up the stack frame and calling another function.
    The registeres eax, ecx, and edx are volatile across function calls ( ie: they will be destroyed unless you save them).
3.) For a quick looping example:


  mov ecx, 10  ; the # of times to loop
my_label:
  push ecx
  push  msg
  push  fmt
  call  _printf
  add  esp, 8
  pop  ecx
  loop my_label


That's a rough scenario of what you're trying to accomplish.  It should point you in the right direction.  ;)
Posted on 2010-11-23 17:19:40 by p1ranha
Besides what p1ranha mentions (which is your main problem, I think), you use "" as a temporary variable to hold the int you get from _scanf. That's fine, but you didn't subtract anything from esp to make room for it, so it will overwrite one of your pushed registers.


push ebp
mov ebp, esp
sub esp, 4 ; make room on the stack for a local variable.
...


You won't have to add anything to esp to "clean up" from this, the epilogue you've got will take care of "freeing" the local variable. (that's why C calls 'em "automatic" as well as several other names)

The topic mentions "conditional", so I'll mention another small nit: "jle" is for signed comparisons, "jbe" is for unsigned. Since your "count" should always be positive, "jbe" would be "more correct". It won't make any difference unless your count exceeds 80000000h. Not really a problem (although your format string for _scanf *does* allow negative values).

Despite the fact that there are a couple things wrong with it, you're "very close", I think!

Best,
Frank

Posted on 2010-11-23 17:58:49 by fbkotler
Thanks for the help guys, it worked! :D
Posted on 2010-11-25 03:18:26 by ashken