flat assembler
Message board for the users of flat assembler.

Index > Main > Few beginner questions

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
rc



Joined: 03 Nov 2019
Posts: 38
Location: Germany
rc
I have a few beginner questions and thought I ask them all at once.
I will just list them:

1. how do I negate a number in a register
2. how do I check if for example eax > ecx
analog all the other operators >=, <, <=, ==, !=
3. how can I create a local variable float and int (not in .data section)
4. analog how do I create a local array and a local string
5. analog how do I free all this memory afterwards when it's not needed anymore

Thank for the help.
These beginner questions answered would make the life a lot easier for a beginner (me).
Post 20 Mar 2020, 17:34
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
1.
Code:
neg eax ; twos compliment negation    

2.
Code:
cmp eax,ecx
jg label ;or ja, jb, jle, etc.    

3.
Code:
sub esp,4 ;space for 4 bytes, 1 dword
mov [esp],eax ;store something there    

4.
Code:
sub esp,4*4 ;space for 4 dwords, or 16 bytes    

5.
Code:
add esp,4*4 ; restore esp to original value    
Note: that using esp directly can cause difficulty if it is mixed with push or pop. Often you will see code that copies the esp value to another register (usually ebp).
Post 20 Mar 2020, 17:44
View user's profile Send private message Visit poster's website Reply with quote
rc



Joined: 03 Nov 2019
Posts: 38
Location: Germany
rc
Thanks for the answer.

So i have the following code, just trying what you said:

Code:
format PE
entry main
section '.code' code readable executable

main:
        int3
        mov eax, -8
        neg eax
        mov ecx, 9
        cmp eax, ecx
        jg myLabel

myLabel:
        push ebp
        mov ebp, esp

        sub esp, 4
        mov [esp], eax
        sub esp, 6*1 ; 6 bytes for 6 characters
        mov [esp+4], "hello",0
        cinvoke printf, [esp+4]

        mov esp, ebp
        pop ebp



section '.idata' import data readable
        library msvcrt,'msvcrt.dll'

        import msvcrt,\
               printf,'printf'     


This might seem to look silly to experienced users, but this doesn't work at the string "hello" part.
Post 20 Mar 2020, 19:02
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
You can't load a 6 byte constant with a single 32-bit instruction. You can split it into two parts.
Code:
mov dword[esp],'hell'
mov word[esp+4],'o' ;upper 8 bits are zero
cinvoke printf, esp    
Post 20 Mar 2020, 19:59
View user's profile Send private message Visit poster's website Reply with quote
rc



Joined: 03 Nov 2019
Posts: 38
Location: Germany
rc
revolution wrote:
You can't load a 6 byte constant with a single 32-bit instruction. You can split it into two parts.
Code:
mov dword[esp],'hell'
mov word[esp+4],'o' ;upper 8 bits are zero
cinvoke printf, esp    


Is this the way one would handle this?

Suppose i have a function (label) where i want to store some strings localy to work with them within this function.
The aproach you showed seems to be a bit error prone.

If not, how would one usually do it?

How would this c-code look like in fasm?
Code:
void myFunc()
{
        const char* myString = "hello";
        printf("%s\n", myString);
}    
Post 20 Mar 2020, 20:20
View user's profile Send private message Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 821
Location: Belarus
DimonSoft
You might want to write something like
Code:
proc myFunc c
     cinvoke printf, .szFormat, .myString
     ret

.szFormat db '%s\n', 0
.myString db 'hello', 0
endp    
Note also that in your case it might be enough to use a single string:
Code:
printf("hello\n");    
Post 20 Mar 2020, 20:36
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
rc wrote:
Suppose i have a function (label) where i want to store some strings localy to work with them within this function.
The aproach you showed seems to be a bit error prone.

If not, how would one usually do it?

How would this c-code look like in fasm?
Code:
void myFunc()
{
        const char* myString = "hello";
        printf("%s\n", myString);
}    
I don't know what C does, but you can also store the string in the code stream.
Code:
jmp @f
.my_string: db 'hello',0
@@: cinvoke printf, .my_string    
It depends upon how you interpret "local"
Post 20 Mar 2020, 20:43
View user's profile Send private message Visit poster's website Reply with quote
rc



Joined: 03 Nov 2019
Posts: 38
Location: Germany
rc
DimonSoft wrote:
You might want to write something like
Code:
proc myFunc c
     cinvoke printf, .szFormat, .myString
     ret

.szFormat db '%s\n', 0
.myString db 'hello', 0
endp    
Note also that in your case it might be enough to use a single string:
Code:
printf("hello\n");    


What does the "c" mean in "proc myFunc c".

Do the variable declarations have to be at the end? Or can they be at the beginning aswell?

Quote:
It depends upon how you interpret "local"

With local i mean that the memory gets freed when the function ends or in asm when jumping back (out of the current label).
Post 20 Mar 2020, 21:11
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
You can use LocalAlloc I suppose, but that would be a lot more work, and you have to initialise it from somewhere before you can use it.
Post 20 Mar 2020, 21:20
View user's profile Send private message Visit poster's website Reply with quote
rc



Joined: 03 Nov 2019
Posts: 38
Location: Germany
rc
Ok, i will then use proc for now. Seems to be easier.

Another question is about the "cmp" and the conditional jumps.

When i have read correctly sets "cmp" the "zf" when both operands are equal. Otherwise not. Therefore the jumps "je" and "jz" are doing the same when one wants to jump when both operands are equal.

My question is: how does "jg" and "jl" know that one operand is greater/lower than the other one - what flags are used by "jg" and "jl" and other conditional jumps?

And can one set flags manually? Let's say i want, after a "cmp" set the zero flag manually. Is that possible?

The reason behind this is, i want to check if a condition is met (e.g. one is greater than the other) and not directly jump somewhere by using jg for example. I want to always use "jz" to jump, therefore i need to manually set the corresponding flags manually.
So i want to do it like this:
- cmp
- check if greater/less etc. without jumping (not using jg/jl etc.)
- set zero flag accordingly
- use jz


Last edited by rc on 20 Mar 2020, 22:42; edited 2 times in total
Post 20 Mar 2020, 22:23
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
There are other flags: Overflow, Carry and Zero are the main arithmetic ones. jg, jb, etc. use various combinations of those flags for their tests.

You can set the flags register directly with a popf instruction. But it isn't usually very useful unless you just want to test something.
Post 20 Mar 2020, 22:33
View user's profile Send private message Visit poster's website Reply with quote
rc



Joined: 03 Nov 2019
Posts: 38
Location: Germany
rc
I edited to above post.

The reason is, i need to generate some fasm code. That code does not have to be efficient, it just has to work.

Therefore it is alot easier from the codeGen side, to just do it the way i described in the above post.
Post 20 Mar 2020, 22:40
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
rc wrote:
The reason behind this is, i want to check if a condition is met (e.g. one is greater than the other) and not directly jump somewhere by using jg for example. I want to always use "jz" to jump, therefore i need to manually set the corresponding flags manually.
So i want to do it like this:
- cmp
- check if greater without jumping (not using jg)
- set zero flag accordingly
- use jz
There is also the setcc instructions, where you can set a register based upon the flags values. But they can't directly set the Z flag. The only way is to use popf.

Instead you might be able to use setg and setz to set two different registers, and then compare with cmp and make your final jz from there.
Post 20 Mar 2020, 22:44
View user's profile Send private message Visit poster's website Reply with quote
rc



Joined: 03 Nov 2019
Posts: 38
Location: Germany
rc
revolution wrote:

Instead you might be able to use setg and setz to set two different registers, and then compare with cmp and make your final jz from there.


Oh didn't know about those.


The Motorolla 68000 instruction set has instructions like:

"SLE D0" to set D0 register when "lessOrEqual"
and than simply jmp by using: "tst d0 beq label"
Code:
sle d0 ; set d0 register when less or equal -> in fasm ?
tst d0 ; test if d0 is set -> in fasm cmp eax, ???
beq myLabel ; jump when z-bit set (by tst) -> in fasm jz myLabel    

Need to mimic the same in fasm.


Last edited by rc on 20 Mar 2020, 23:23; edited 1 time in total
Post 20 Mar 2020, 23:16
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
There are also cmovcc instructions.

Various combinations of the conditional instructions might make your code more efficient. It might also allow you to avoid using jcc completely.
Post 20 Mar 2020, 23:20
View user's profile Send private message Visit poster's website Reply with quote
rc



Joined: 03 Nov 2019
Posts: 38
Location: Germany
rc
revolution wrote:
There are also cmovcc instructions.

Various combinations of the conditional instructions might make your code more efficient. It might also allow you to avoid using jcc completely.


Where can i read more about these instructions? I can't find any of those in the fasm documentation.
Post 20 Mar 2020, 23:32
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
You can download the Intel and/or AMD instruction set documentation directly from their websites.

There are also quite a number of other websites that have scraped the docs and posted online all the intricate details of each x86 instruction.
Post 20 Mar 2020, 23:41
View user's profile Send private message Visit poster's website Reply with quote
CandyMan



Joined: 04 Sep 2009
Posts: 319
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
CandyMan
revolution wrote:
There are also cmovcc instructions.

Various combinations of the conditional instructions might make your code more efficient. It might also allow you to avoid using jcc completely.


It's a pity there are no cmovcc instructions with the destination memory operand.

_________________
smaller is better
Post 21 Mar 2020, 16:26
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17671
Location: In your JS exploiting you and your system
revolution
CandyMan wrote:
It's a pity there are no cmovcc instructions with the destination memory operand.
It is also a pity that you can't use cmovcc to avoid reading null pointers. The second operand is always read.
Code:
xor eax,eax ; null pointer. Z flag is now set
cmovnz eax,[eax] ; CRASH! Fails when eax==0 regardless of the Z flag value    
Post 21 Mar 2020, 16:46
View user's profile Send private message Visit poster's website Reply with quote
DimonSoft



Joined: 03 Mar 2010
Posts: 821
Location: Belarus
DimonSoft
revolution wrote:
CandyMan wrote:
It's a pity there are no cmovcc instructions with the destination memory operand.
It is also a pity that you can't use cmovcc to avoid reading null pointers. The second operand is always read.
Code:
xor eax,eax ; null pointer. Z flag is now set
cmovnz eax,[eax] ; CRASH! Fails when eax==0 regardless of the Z flag value    

I double that. The pitiest pity of general purpose x86 instructions.
Post 22 Mar 2020, 14:02
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  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-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.