flat assembler
Message board for the users of flat assembler.
Index
> Main > NOT Operator and Functions |
Author |
|
beppe85 17 Jan 2005, 11:40
1. NOT inverts every bit of the value. The 0d(a string of all 0's in binary) NOTed becomes a string of all 1's, which is -1d. The number 1d have every bit as 0b but the rightmost is 1b.
To turn a 0 into 1 or vice-versa, you can use: Code: inc eax and eax, 1 2. You don't have to use enter and leave. I don't use them. The handling of parameters depends on the calling convention. stdcall frees stack frame inside routine, but cdecl does this after returning from that. There are macros in FASM that does this automatically. |
|||
17 Jan 2005, 11:40 |
|
denial 17 Jan 2005, 12:13
Thank you very much,
but how can I then get a NOT Operator like In C or Basic? They really behave on another way than the NOT Operator in FASM does... Everything below 0 gets 0... 0 gets 1... 1 gets 0.... and everything above 1 gets 0. 2. I think I need to understand the system behind. I know that FASM got some macros, but I don't feel good if I just use them... oh and well what about local data? Still seems to be confusing for me |
|||
17 Jan 2005, 12:13 |
|
Madis731 17 Jan 2005, 13:29
its called neg - you mean negative
in C not 0 also gives you -1. NEG in asm is defined NOT reg/mem +1 in C and BASIC you just can't "see" how they behave try to put inline INT3-s in your C-code and see the miracle of 0-s turning to -1 (0FFFFFFFFh) |
|||
17 Jan 2005, 13:29 |
|
vid 17 Jan 2005, 14:20
you have mistaken C's logical not (!) with numerical not (~). "not" instruction in assembly is like C's "~" operator. If you want to invert condition (logical not) just use "jne" instead of "je" etc, it's usually used only in "if"s.
|
|||
17 Jan 2005, 14:20 |
|
denial 17 Jan 2005, 14:29
Thank you very much... I think I'm a bit confused... so "true" in C is -1... I did not know it.
Well however I want the NOT I described above but also NEG or both NOT and NEG cannot do this as I want it: Everything except 0 should get 0, and 0 should get 1. And what about local data? |
|||
17 Jan 2005, 14:29 |
|
JohnFound 17 Jan 2005, 15:38
denial wrote: And what about local data? To understand the stack frames (don't think it is new stack - it is the same stack) you simply need: 1. Create some small Win32 application using FASM stdcall.inc macroses, or simply download some example that uses procedures with local variables. 2. Compile it and open the .exe in OllyDbg. 3. Step through the program and see what happens with esp and ebp (ebp is the pointer to the stack frame and to arguments of the procedures). Since esp can be directly used as an pointer, some people (and compilers) prefere to use directly esp as a pointer to arguments and local variables, but it is not good approach IMHO (at least for beginers). FASMs stdcall.inc library uses esp as pointer. 4. Read "Tajga tutorial" - there is still nothing about stack frames, but you will understand many new things there. Here: http://decard.net/?body=docs 5. Read some CPU manual - there everything is explained in extended way. Regards. |
|||
17 Jan 2005, 15:38 |
|
vid 17 Jan 2005, 16:23
Quote: so "true" in C is -1 no, true in C is anything but 0. So C's Code: if (something) { <body> } AfterIF: in assembly looks like Code: cmp something,0 jz AfterIF <body> AfterIF: and Code: if (something) <body1> else <body2> AfterIF: is Code: cmp something,0 jz ELSE <body1> jmp AfterIF ELSE: <body2> AfterIF: About local data: Better don't care with it now too much, it will probably just confuse you. You can use macros Code: proc ProcedureName,arg1,arg2 ;local data here loc1 dd ? loc2 dd ? enter mov eax,10 mov [loc2],eax sub eax,20 mov [loc1,eax] ret endp And don't forget you can't initialize local data this way, so Code: proc ProcedureName,arg1,arg2 ;local data here loc1 dd 10 ;[loc1] WON'T contain 10 enter ... ret endp |
|||
17 Jan 2005, 16:23 |
|
denial 17 Jan 2005, 16:38
Thank you for your answers.
@JohnFound: Yes I read the tutorial already, thank you @vid: Thank you, with macros it seems to be pretty easy... is there an efficient way to pass a string-constant to a prog? It is not very easy I think, isn't it? I thought about passing a pointer but then I would need to declare the string before. What if I just want to pass an un-declared string constant? OH AND: Is there a difference between "ret" and "return"? I used them both already. Don't know what's the difference... |
|||
17 Jan 2005, 16:38 |
|
vid 17 Jan 2005, 16:53
to declare string constant, declare it as global variable, preferably with a very unique name, like
Code: db _fatal_error "Fatal error",0 db _not_enough_memory,"Not enough memory",0 it is something like standard to prepend name with "_", to differ it from other labels. "retn" is instruction, "ret" is macro which returns from procedure (removes all things declared by "enter", like space for local variables) and should be used to return from procedure declared by "proc"/"enter", and "return" is "ret" in old standard (previous versions of "proc" macros, now oblosete). But I am not sure about "return". [quote]What if I just want to pass an un-declared string constant?[quote] What do you mean by undeclared string constant? |
|||
17 Jan 2005, 16:53 |
|
denial 17 Jan 2005, 17:00
Well for example:
(...) invoke MessageBox,0,"Hello!","Caption",MB_OK (...) Hello! and Caption are undeclared, I just passed the string constants. Is that possible with own functions? So I want to use strings inside the argument list. But I thought this could be a problem because of the different sizes. Can these macros handle them? |
|||
17 Jan 2005, 17:00 |
|
vid 17 Jan 2005, 17:05
oh, this.
This is handled by macro "invoke", if it locates string in argument list, then it declares string for you, like Code: invoke MessageBox,0,_str1,_str2,MB_OK is preprocessed (after urolling macro] to Code: push MB_OK push _str2 push _str1 push 0 call [MessageBox] and when it detects string, it does it like this: Code: MessageBox,0,"aaaa","bbbb",MB_OK to Code: push MB_OK push _str1 jmp Behind_str1 _str1 db "aaaa",0 Behind_str1: push _str2 jmp Behind_str2 _str2 db "aaaa",0 Behind_str2: push dword 0 call [MessageBox] |
|||
17 Jan 2005, 17:05 |
|
denial 17 Jan 2005, 18:45
Ok thank you for your help! I've got ONE LAST question. If this is clear, I promiss that you'll never hear again from me (at least for some days )
I know that the result which is returned by a function should get stored in EAX... alright but what if I want to return a string? Can I save the pointer in EAX or something? |
|||
17 Jan 2005, 18:45 |
|
vid 17 Jan 2005, 19:58
Quote: f this is clear, I promiss that you'll never hear again from me (at least for some days ) don't worry, i have unlimited internet access now. You never return string, you only can return pointer to string, just like in C - char* strlen(...), but problem is that if string is created by your function, you have to allocate it there, but it must also be freed somewhere so don't forget about it. |
|||
17 Jan 2005, 19:58 |
|
denial 18 Jan 2005, 09:53
O..k... why does this one not work? *confused* It says that the operand size is not specified?
proc retint,arg1,arg2 mov ecx,dword [arg1] mov edx,dword [arg2] add ecx,edx mov eax,ecx return endp proc trmain invoke retint,3,3 mov ecx,eax return endp |
|||
18 Jan 2005, 09:53 |
|
JohnFound 18 Jan 2005, 11:48
At first - use "stdcall", not "invoke".
Invoke is for imported functions mainly. At second - use [code][/code] tags in your posts to make source code properly formated Regards |
|||
18 Jan 2005, 11:48 |
|
denial 18 Jan 2005, 13:02
Ok thank you, I agree I should use the code-tag, I'm sorry. Next time I'll do it.
|
|||
18 Jan 2005, 13:02 |
|
vid 19 Jan 2005, 00:26
i quess you are forgeting "enter" directive
Code: proc retint,arg1,arg2 ;local variables can be here enter ;<------------ mov ecx,dword [arg1] mov edx,dword [arg2] add ecx,edx mov eax,ecx return endp proc trmain ;local variables can be here enter ;<-------- invoke retint,3,3 mov ecx,eax return endp |
|||
19 Jan 2005, 00:26 |
|
JohnFound 19 Jan 2005, 02:49
vid wrote: i quess you are forgeting "enter" directive Enter is not mandatory in Privalovs stdcall.inc library. The problem of the above code is that it uses "invoke" to directly call procedure instead of "stdcall" - as far as "invoke procname" is actually "stdcall [procname]" FASM complains about the size of "procname" - it is label and have no size at all. Regards. |
|||
19 Jan 2005, 02:49 |
|
denial 19 Jan 2005, 09:31
Thank you very much for all your help
Yes with stdcall it works. |
|||
19 Jan 2005, 09:31 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.