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 |
|
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..
|
|||
05 Apr 2012, 17:48 |
|
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 |
|||
06 Apr 2012, 15:11 |
|
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! Thanks a lot, I'll go read it now. |
|||
06 Apr 2012, 15:24 |
|
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 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. |
|||
06 Apr 2012, 15:41 |
|
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...
|
|||
07 Apr 2012, 16:47 |
|
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 |
|||
07 Apr 2012, 19:45 |
|
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?
|
|||
07 Apr 2012, 21:06 |
|
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! |
|||
08 Apr 2012, 00:22 |
|
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.
|
|||
08 Apr 2012, 04:24 |
|
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 |
|||
08 Apr 2012, 10:52 |
|
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 |
|||
08 Apr 2012, 22:02 |
|
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] |
|||
08 Apr 2012, 22:31 |
|
Inagawa 09 Apr 2012, 07:36
Ah, excellent! It works now. I will post the update on the "game" sometime today.
|
|||
09 Apr 2012, 07:36 |
|
Inagawa 09 Apr 2012, 17:58
This is the state of the game (nothing to play yet)
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 |
|||
09 Apr 2012, 17:58 |
|
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. 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? |
|||
10 Apr 2012, 06:43 |
|
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. |
|||
10 Apr 2012, 14:49 |
|
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.
How do I invoke my own functions, though? "Operand size not specified" Which operand? |
|||
10 Apr 2012, 15:43 |
|
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". |
|||
10 Apr 2012, 16:17 |
|
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.
|
|||
10 Apr 2012, 16:34 |
|
Goto page Previous 1, 2, 3, 4, 5, 6, 7 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.