flat assembler
Message board for the users of flat assembler.

Index > Main > Where to start?

Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
Author
Thread Post new topic Reply to topic
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 05 Apr 2012, 17:48
Ha, it works! Damn this gave me nightmares. The book Prophet recommended specifically tells me to use FMULP ST1, which didn't work..
Post 05 Apr 2012, 17:48
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 06 Apr 2012, 12:06
Thanks for the replies about the floating point, but now the killer question that I have been saving:

Functions. I have been trying to wrap my head around this forever.

Every function has its own Stack Frame, right? Before I call a function, I PUSH the parameters and then use CALL. EIP(Return Address) gets pushed on the stack, and execution jumps to the label of the function. At that point, I have to save EBP, MOV ESP to EBP and subtract a power of 4 from the stack to cover the memory usage of auto variables.
I understand it without a problem so far. I even drew a map of stack to really understand what is going on and why am I subtracting or MOVing.
The execution goes through successfully, I MOV the EBP into the ESP, POP EBP and RET, which jumps to the first byte after where EIP points. I hope I got this right. Now, this is a function, right? This whole process. So, what exactly is proc, _stdcall, _cdecl, cinvoke, ccall... Do I have to use any of these, or is the process I just desribed the bread and butter of assembly function programming?

Is there any reason not to use them(slow), is there any reason to DO use them(fast, easy, etc)? I found some foggy descriptions of each, but honestly, I don't have the slightest clue what to do. I really value your help, so if you have the time to really explain, I would be most grateful, if you don't, could you please point me to a book containing the explanation? Thanks a lot, I hope I'm not too much of a bother... yet Very Happy
Post 06 Apr 2012, 12:06
View user's profile Send private message Reply with quote
ProphetOfDoom



Joined: 08 Aug 2008
Posts: 120
Location: UK
ProphetOfDoom 06 Apr 2012, 15:11
Hi,

Sorry I didn't reply, I thought my original explanation was adequate.

Re: your problem with unnecessary "jmp"s around functions: this can be avoided by putting all your functions at the end of your program, *after* the call to "exit". That way they will only execute when you explicitly call them. Hope that clears things up.

What you said about functions is pretty much correct (though you can subtract any multiple of 4 from ESP, not just a power).

There are various calling conventions used on Win32 with subtly different rules. For example, with the cdecl calling convention, the called function does not remove its own arguments from the stack. It is the responsibility of the calling code to do an "add esp, 16" or whatever number, after the call. The stdcall convention requires the called function to remove its own arguments with an argument to the RET instruction eg "ret 16". You can use fasm's macros do do this work for you, or you can just do it yourself (which is what i usually do). I doubt there is much if any performance hit from using the macros, it's just personal preference.

This article explains it all in a non-foggy way:

http://www.codeproject.com/Articles/1388/Calling-Conventions-Demystified
Post 06 Apr 2012, 15:11
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 06 Apr 2012, 15:24
Yes, I have figured that out from your original post, thanks.

Since English is not my native language, I got "power" and "multiple" confused, my bad! Smile

Thanks a lot, I'll go read it now.
Post 06 Apr 2012, 15:24
View user's profile Send private message Reply with quote
gunblade



Joined: 19 Feb 2004
Posts: 209
gunblade 06 Apr 2012, 15:41
... Man I hate pressing the Post Reply instead of the submit when using that quick reply function..

So.. to reiterate what i typed (and didnt post, and my browser forgot when i hit back..):

The stack frame saving is considered good practice, and a neat way of having local variables on the stack, and easier way to clean it. It is always used in C, so you'll see if you disassemble compiled code that it'll always contain the ebp-saving and ebp-restoring code at the start and end of each function. However.. its not a requirement, and if you dont plan to use local variables stored on the stack in a function, then you dont need to do it. I rarely save ebp, because I usually use variables in the data segment, or at a push, i use the stack relative to ESP rather than EBP.. still, thats probably not recommended.. so if you want to keep to good practices, then save it Smile

if i recall correctly, proc is a macro that lets you define a "function" and does the ebp storing/restoring for you, and also deals with allocating space for parameters? If you want to know for sure, then check the include files that come with the windows fasm package, the proc definition should be in there somewhere.

As for the others.. stdcall/cdecl, its two different ways of deffining functions. Theres two things that can differ when you call functions.. the way you pass parameters, and who cleans up the stack.. The parameters can be passed either by registers (common in linux syscall syntax), but both stdcall and cdecl use stack-based parameter passing. The main difference between them is who cleans up the stack. One requires the function to "free" any parameters passed on the stack before returning, whetheras the other requires the caller to clean up the stack after the function has returned. Win32API and the C library use different ones.. which is why you use either invoke or cinvoke depending what library functions you're calling.
Post 06 Apr 2012, 15:41
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 07 Apr 2012, 16:47
Thanks for the additional info. I'll get back to you later. I have finished the book Prophet suggested. I am now trying to get some additional info from "Assembly Language Step-by-Step - Programming with Linux, 3rd Edition". I kinda feel like I partially know the basics, but can't move forward. I need to somehow break through...
Post 07 Apr 2012, 16:47
View user's profile Send private message Reply with quote
Stephen



Joined: 13 Aug 2011
Posts: 30
Stephen 07 Apr 2012, 19:45
The pushing stuff to the stack is how it's most often done in Linux/Windows/C and lots of other places. As you are playing with windows, that's what you are going to see almost all the time. Dos, bios, lots of controllers and older asm functions tended to pass things in the cpu registers and often use the register values as a pointer to data in memory some where. passing data in registers still gets used where speed is a large factor, as it saves a few clock cycles.

Try writing a program that does something you want
Post 07 Apr 2012, 19:45
View user's profile Send private message Visit poster's website Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 07 Apr 2012, 21:06
Is there anything anyone would suggest? With your experience, maybe you have an idea for a project that would stress what I know, force me to think, but still allow me to learn something and move forward. There is just so little that I know how to do in assembler! It's frustrating. I hate the damn C functions everywhere, but no one shows how to print to the console with pure assembler, even the new languages like D are using C.. But I digress, does anyone have an assignment for me, seeing that I made it through the first and second one from dancho?
Post 07 Apr 2012, 21:06
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
AsmGuru62 08 Apr 2012, 00:22
Well, the OS (Windows) provides the API to work with, so you really do not need the pure assembler for an output to console. You need a pure assembler to do the stuff that windows does not know to do.

Write a simple console game just for fun!
Post 08 Apr 2012, 00:22
View user's profile Send private message Send e-mail Reply with quote
bubach



Joined: 17 Sep 2004
Posts: 341
Location: Trollhättan, Sweden
bubach 08 Apr 2012, 04:24
As long as you don't enter any graphics mode you can program a .com file using old DOS interrupts and tutorials. It will run fine even under Windows 7 with the built in Windows compatibility for 16-bit DOS programs. By far the easiest way to get into it, compared to using Win32 API's. Also, there's lots of old tutorials and interrupt lists to google for.
Post 08 Apr 2012, 04:24
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 08 Apr 2012, 10:52
I'll try the console game then.

Edit: A one quick question before I go, the name mangling. Where do I find how was the name mangled? Some functions have underscores in front of them, while others are really strangely changed like "_fgetchar", some do have underscores, like "_exit", and some don't like "gets", "atoi", etc.. How am I supposed to know which ones do and which ones don't? Also the kernel32 functions don't seem to have mangling "ExitProcess". ??

As to what you guys told me about winapi, I had a long reply, but in the end I decided to google more, because I found out I can't find the words to ask the right questions. So until I do, I'll just devote my time to the game. Thanks a lot for the time it takes to answer my questions
Post 08 Apr 2012, 10:52
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 08 Apr 2012, 22:02
And also if someone could please show me how to move the cursor inside the console. I have been playing with it the whole day but it just doesn't work.

Code:
;=============================================================================

struct COORD
        posX db 9
        posY db 3
ends


;=============================================================================
section '.text' code readable executable
start:

  virtual at ebx
        oCOORD COORD
  end virtual

  ;=============================================
  invoke       GetStdHandle, -11
  mov          [__consoleHandle], eax
  cinvoke      printf, 'eax'
  ;invoke       GetStdHandle, -11
  ;mov          [__consoleHandle+1], eax

  ;=== CONSOLE CARET =============================
  mov          [oCOORD.posX], 10
  mov          [oCOORD.posY], 3
  lea          eax, [oCOORD.posX]
  push         eax
  push         [__consoleHandle]
  call         [SetConsoleCursorPosition]
  ;invoke       SetConsoleCursorPosition, __consoleHandle, [oCOORD]

  invoke       SetConsoleTextAttribute, [__consoleHandle+1], 74
  cinvoke      printf, 'eax'


  ;=== LEAVE CONSOLE OPEN ========================
  cinvoke      getchar                            ; Leave console open
  cinvoke      exit, 0                            ; C-Style exit ?
    


After lots of sweat, pain and blood I have figured out things like setting multiple colors, but I am totally stuck at structs. I simply have no idea how to use them. I made the console stop crashing whenever I use the function now, but it simply doesn't do anything. Thanks for the help
Post 08 Apr 2012, 22:02
View user's profile Send private message Reply with quote
ProphetOfDoom



Joined: 08 Aug 2008
Posts: 120
Location: UK
ProphetOfDoom 08 Apr 2012, 22:31
Hi,

From a quick look at the documentation, it seems a COORD structure is made of two shorts, rather than two bytes, so using db to declare the fields would be wrong. Also, you're using LEA so you're passing the address of the structure - the msdn docs say you should pass the structure itself (which is two shorts, so it's the size of a 32 bit integer).

You could define such a structure like this:

Code:
my_point dw 10, 3
    


And pass it like:

Code:
push dword [my_point]
    
Post 08 Apr 2012, 22:31
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 09 Apr 2012, 07:36
Ah, excellent! It works now. I will post the update on the "game" sometime today.
Post 09 Apr 2012, 07:36
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 09 Apr 2012, 17:58
This is the state of the game (nothing to play yet)

Image

And here is the code so far. Link

I'd be happy if someone checked it out and told me if I am going in the right direction, if my code is readable, if the functions are alright etc. I have not commented the code because all the names should be self-explanatory. Also if you guys know why I cannot call the SetConsoleTitle (it is supposedly in KERNEL32.DLL) function. It throws up an error about there not being any function of such name defined. Thanks a lot
Post 09 Apr 2012, 17:58
View user's profile Send private message Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 10 Apr 2012, 06:43
Well, to be honest. I think this is it. In higher level language I'd do it using objects and helper functions, but I can't seem to make the code less complex.

I have code like: (Can't use invoke, because in other instances I am iterating through a set of positions like this and I need to upload only X or Y at a time and I have no idea how to do that with invoke.)
Code:
  push         WORD 28
  push         WORD 24
  push         [__consoleHandle+1]
  call         [SetConsoleCursorPosition]
    


and even if I created a helper function "MoveCursor", I'd still have to call it the exact same way.
Code:
  push         WORD 28
  push         WORD 24
  push         DWORD 1
  call         %MoveCursor%
    


Elegant, isn't it. Very Happy I'll have to read up on creating objects in assembly on the fly, because if I tried to do it by using buffers (I have a function parsing a text file on the map area of the window), the code gets so extremely complex I can't move forward.. Any tips whatsoever?
Post 10 Apr 2012, 06:43
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
AsmGuru62 10 Apr 2012, 14:49
invoke is just one line instead of 4 lines.
I think invoke is more elegant.
Also, I do not get your explanation why you're not using invoke.

Advice: to make code less complex - use a lot of small functions.
The code will be much more readable and complex stuff will fit into less lines of code.
From the small functions build more complex functions and so on.
Post 10 Apr 2012, 14:49
View user's profile Send private message Send e-mail Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 10 Apr 2012, 15:43
Actually - now, that I've sat down to explain why I don't use invoke, I see that I have no good explanation and my previous reasoning was totally faulty. I like your style. Smile

How do I invoke my own functions, though? "Operand size not specified" Which operand?
Post 10 Apr 2012, 15:43
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
AsmGuru62 10 Apr 2012, 16:17
invoke is for Windows API.
Use CALL to execute your own functions:
Code:
YourFunction:
       ;
   ; put some code here ...
    ;
   ret

...

  call    YourFunction
    

The beauty of functions is an ability to use local labels of the same name and have no conflict, like so:
Code:
;
; PROCEDURE #1
;
Function1:
      pusha
       ...
 jmp     .exit
       ...
.exit:
   popa
        ret
;
; PROCEDURE #2
;
Function2:
   pusha
       ...
 jmp     .exit
       ...
 jmp     Function1.exit
      ...
.exit:
   popa
        ret
    

In this example label ".exit" defined twice: inside its own function.
And that is normal for FASM - no conflict is here.
You even can jump inside the other function by specifying the name of it,
like: "Function1.exit".
Post 10 Apr 2012, 16:17
View user's profile Send private message Send e-mail Reply with quote
Inagawa



Joined: 24 Mar 2012
Posts: 153
Inagawa 10 Apr 2012, 16:34
Wow, I had no idea about the labels! I was constantly afraid of messing with the names, naming my labels !FileName_LoopName:. Cool I don't have to do that anymore. Smile
Post 10 Apr 2012, 16:34
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.