flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > push dword myNumber in 64-bit mode.

Author
Thread Post new topic Reply to topic
alwaysnub



Joined: 30 Mar 2013
Posts: 26
alwaysnub 06 Apr 2013, 01:34
push dword someNumber is creating an error when use64 is defined.
Is it not supported in the flat assembler yet?
According to the Intel® 64 and IA-32 Architectures
Software Developer’s Manual, pusing immediate values of dword are supported in 64-bit mode.
Post 06 Apr 2013, 01:34
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4043
Location: vpcmpistri
bitRAKE 06 Apr 2013, 02:18
Let me guess (since you didn't post any code): The high bit of the DWORD is set? Only signed DWORDs are supported - they get extended into the upper DWORD on the stack. For example, change "push $80000000" to "push -$80000000", and the top QWORD on the stack will be $FFFFFFFF80000000.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 06 Apr 2013, 02:18
View user's profile Send private message Visit poster's website Reply with quote
alwaysnub



Joined: 30 Mar 2013
Posts: 26
alwaysnub 06 Apr 2013, 04:14
No my initial problem was because i was specifing the size dword in the operande, for what ever reason only word or nothing is accepted when use64 is defined.

Will unsigned values be supported in future releases of fasm?
Its shouldn't be a problem for the processor because -$80000000 and 80000000 look the same in the bytes when compiled, so its just a matter of how its displayed.
Post 06 Apr 2013, 04:14
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4043
Location: vpcmpistri
bitRAKE 06 Apr 2013, 06:29
It's my understanding this functionality is by design - previously, FASM did take inputs which resulted in software errors being silently generated. It isn't the same. The processor isn't pushing a DWORD - that is why DWORD can't be specified and also the reason the range is as it is.

How about a macro?
Code:
macro push_dword val {
  if val eqtype 0
    push ((val+$80000000)and $FFFFFFFF)-$80000000
  end if
}    
...only the first dword on the stack is valid - what you are expecting.

Vol 2B 4-333, Second to last paragraph states immediate operands are sign-extended.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 06 Apr 2013, 06:29
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8354
Location: Kraków, Poland
Tomasz Grysztar 06 Apr 2013, 09:10
There is no instruction than pushes dword on stack in long mode - the one you are referring to, pushes qword on the stack, but in the machine code it uses the signed dword to encode this value. This limits the range of qword values that you can push this way. You can push 000000007FFFFFFFh, you can push 0FFFFFFFF80000000h (that is -80000000h), but you cannot push 0000000080000000h.

I designed the fasm's syntax with the idea in mind that it should focus on the functionality of instruction, not an encoding. I see the assembly language as an abstraction that let's programmer think in categories of what the instructions do, not how they are encoded.
Post 06 Apr 2013, 09:10
View user's profile Send private message Visit poster's website Reply with quote
alwaysnub



Joined: 30 Mar 2013
Posts: 26
alwaysnub 06 Apr 2013, 14:10
So basicly from what i have gathered...

Immediate bytes are always sign-extended to words.
Immediate words are pushed as words.
Immediate dwords are pushed as dwords in 32- and 16-bit mode.
Immediate dwords are sign-extended to qwords in 64-bit mode.

So:
Only immediate words and dwords can be pushed in 32- and 16-bit mode.
Only immediate words and qwords can be pushed in 64-bit mode.

And based on this logic, we can only push signed qwords in 64-bit mode. Basicly...

What about call near dword myValue operations in 64-bit mode?
They are sign-extended in 64-bit mode, so i should keep execution addresses and calls no more than 2147483647 bytes apart, Right?

Also nice cheat bitRAKE, that will work good when i want to make it look like im only pushing dwords. Wink
Post 06 Apr 2013, 14:10
View user's profile Send private message Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4043
Location: vpcmpistri
bitRAKE 06 Apr 2013, 18:23
Try the follow in a debugger - watch what happens. Make mistakes and live to tell the tale. Wink
Code:
push byte -1
push word -1
push qword -1    
What happens to RSP register? How many bytes are these instructions?

It is good to keep the base address of your application low in memory. This is not because of CALL instructions though. It's because of other addresses not needing to referenced by R* registers. This has the added complication of tracking the source of all addresses - external addresses need to be handled as 64-bit. Most people don't bother and use 64-bit internal and external to their application.
Code:
HINSTANCE = $10000 ; allows us to use 32-bit addresses for almost everything
format PE64 GUI 5.0 at HINSTANCE    
If you want to write small code then using the default address and operand size is one way. LEA instruction is a good example: LEA EAX,[RAX*4+RDX] -- notice how the registers in brackets are 64-bit, but the result is 32-bit register. These are the defaults, and no "extra" bytes are generated.

_________________
¯\(°_o)/¯ “languages are not safe - uses can be” Bjarne Stroustrup
Post 06 Apr 2013, 18:23
View user's profile Send private message Visit poster's website Reply with quote
alwaysnub



Joined: 30 Mar 2013
Posts: 26
alwaysnub 06 Apr 2013, 20:12
ok, i figured it out. Cool

6A = PUSH BYTE - Sign-Extended to operande size (current bit mode).
68 = If current-bit mode = 16 then its PUSH WORD else if its 32-mode its PUSH DWORD.
In 64-Bit mode, PUSH DWORD gets sign-extended to a 64-Bit value.

So basicly our options are:
In 16 bit mode, we can push an immediate sign-extended byte or word.
In 32 bit mode, we can push an immediate sign-extended byte or dword.
In 64 bit mode, we can push an immediate sign-extended byte or sign-extended dword.
with the exception of prefixes.

I was only a little off on how it worked. Razz
Thanks!
Post 06 Apr 2013, 20:12
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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.