flat assembler
Message board for the users of flat assembler.

Index > Main > NOT Operator and Functions

Author
Thread Post new topic Reply to topic
denial



Joined: 12 Sep 2004
Posts: 98
denial 17 Jan 2005, 10:10
Hello,

I've got some new questions I'd like to get answered. Smile
I already searched this board for answers but unfortunately, I can't open alot of threads. Maybe the board is broken? Well however...

1. When I MOV the value 0 to ECX and perform a NOT operation with it, the result is -1. Shoudn't it be 1? Also other values operated with NOT give me some odd results. One reason I guessed is, that the integers I use are signed. Maybe NOT inverts also the bit that holds the sign? How to get rid of these problems?

2. I want to use functions that can handle local data and also parameters. For local data, I know that I have to use enter and leave to create a stack with the needed size of bytes used by the parameters, is that true? But I didn't really understand this. How can I push and use the arguments into that new stack then, and what does the second parameter of the enter-command mean?

About the parameters... I know that I've to push them in reversed order onto the stack (at least when I use cdecl and stdcall calling convention), but I think I also have to pop them then inside my function? And how is this possible while I use the stack frame I created with enter for local data?

I know maybe my questions are a bit complicated, but the answers are, as always Wink, really important.

Thank you in advance
Post 17 Jan 2005, 10:10
View user's profile Send private message Reply with quote
beppe85



Joined: 23 Oct 2004
Posts: 181
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.
Post 17 Jan 2005, 11:40
View user's profile Send private message Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
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 Sad
Post 17 Jan 2005, 12:13
View user's profile Send private message Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
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)
Post 17 Jan 2005, 13:29
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
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.
Post 17 Jan 2005, 14:20
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
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. Sad

And what about local data? Wink
Post 17 Jan 2005, 14:29
View user's profile Send private message Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 17 Jan 2005, 15:38
denial wrote:
And what about local data? Wink


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.
Post 17 Jan 2005, 15:38
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
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
    
Post 17 Jan 2005, 16:23
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
denial 17 Jan 2005, 16:38
Thank you for your answers.

@JohnFound: Yes I read the tutorial already, thank you Smile

@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... Confused
Post 17 Jan 2005, 16:38
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
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?
Post 17 Jan 2005, 16:53
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
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?
Post 17 Jan 2005, 17:00
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
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]
    
Post 17 Jan 2005, 17:05
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
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 Wink)

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? Sad Can I save the pointer in EAX or something?
Post 17 Jan 2005, 18:45
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
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.
Post 17 Jan 2005, 19:58
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
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
Post 18 Jan 2005, 09:53
View user's profile Send private message Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
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 Exclamation

Regards
Post 18 Jan 2005, 11:48
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
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.
Post 18 Jan 2005, 13:02
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
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
    
Post 19 Jan 2005, 00:26
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
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.
Post 19 Jan 2005, 02:49
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
denial 19 Jan 2005, 09:31
Thank you very much for all your help Smile Smile Smile
Yes with stdcall it works.
Post 19 Jan 2005, 09:31
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.