flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > big endian macros

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



Joined: 04 Oct 2003
Posts: 86
Ralph 07 Aug 2004, 22:59
Hey,
I recently made fasm assemble code for another CPU using macros, but that CPU was big endian so I made these:
Code:
macro dd op {
   dd 0 or ((op and 0FF000000h) shr 24) or \
           ((op and 000FF0000h) shr  8) or \
           ((op and 00000FF00h) shl  8) or \
           ((op and 0000000FFh) shl 24)
}
macro dw op {
   dw 0 or ((op and 0FF00h) shr 8) or \
           ((op and 000FFh) shl 8)
}
    

Slap in a few more macros and you should be able to make fasm work for almost any architecture.
Post 07 Aug 2004, 22:59
View user's profile Send private message Reply with quote
wht36



Joined: 18 Sep 2005
Posts: 106
wht36 08 Nov 2008, 16:14
Many thanks, just what I need for my byte coder!
Post 08 Nov 2008, 16:14
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20300
Location: In your JS exploiting you and your system
revolution 08 Nov 2008, 16:24
You may also want to test for overflow by checking that the high part of op is either all zeros (or all ones for signed values).

BTW: the "0 or " part is not needed.
Post 08 Nov 2008, 16:24
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 08 Nov 2008, 16:58
Ralph,

Code:
macro dw [val] { db (val) shr 8 and 0xFF, (val) and 0xFF }
macro dd [val] { dw (val) shr 16 and 0xFFFF, (val) and 0xFFFF }; code reuse
struc dw [val] { common dw val }
struc dd [val] { common dd val }

dw_big_endian:  dw 0x1200+0x34, 0x5678  ; here you will see the purpose of () and []
dd_big_endian   dd 0x9ABCDEF0           ; that's why duplicate macro with struc    
Don't forget about ? and x dup (y) as arguments, that complicate things much more. Wink
Post 08 Nov 2008, 16:58
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 08 Nov 2008, 17:48
Quote:

struc dw [val] { common . dw val }
struc dd [val] { common . dd val }
Post 08 Nov 2008, 17:48
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 08 Nov 2008, 19:44
LocoDelAssembly,

No need for that, label is defined even without using the dot.

By the way, here is another variant:
Code:
macro big_endian datadef*, [tail] {
common
    local ..start, ..datasize, ..dataptr, ..val1, ..val2
    match datadef_directive val,datadef \{
        virtual
            datadef_directive ?
            ..datasize = $-$$
        end virtual
        ..start = $
        if tail eq
                datadef
        else
                datadef, tail
        end if
        repeat ($ - ..start) / ..datasize
            ..dataptr = ..start + ..datasize*(%-1)
            repeat ..datasize/2
                load ..val1 byte from ..dataptr + (%-1)
                load ..val2 byte from ..dataptr + ..datasize - %
                store byte ..val1 at ..dataptr + ..datasize - %
                store byte ..val2 at ..dataptr + (%-1)
            end repeat
        end repeat
    \}
}
struc big_endian datadef*, [val] { common big_endian datadef, val }

repeat 5
    big_endian dq 3 dup (%*25), ?
end repeat

rept 5 counter {
    here#counter big_endian dq 25*here#counter
}    
This time the idea was "let directive do it's work, then convert the result." big_endian used as prefix for dw/dd/dq/whatever (hence match to separate directive from first expression and if to combine them back correctly and eliminate extra comma from struc). Good even for db Wink
Post 08 Nov 2008, 19:44
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 08 Nov 2008, 21:41
Quote:

No need for that, label is defined even without using the dot.

And it is even said in the documentation but I don't know why I remember myself having problems for not defining the label ".:" (or using ". dX" on specialized cases like this one). Confused
Post 08 Nov 2008, 21:41
View user's profile Send private message Reply with quote
wht36



Joined: 18 Sep 2005
Posts: 106
wht36 09 Nov 2008, 03:15
baldr wrote:
Ralph,

Code:
macro dw [val] { db (val) shr 8 and 0xFF, (val) and 0xFF }
macro dd [val] { dw (val) shr 16 and 0xFFFF, (val) and 0xFFFF }; code reuse
struc dw [val] { common dw val }
struc dd [val] { common dd val }

dw_big_endian:  dw 0x1200+0x34, 0x5678  ; here you will see the purpose of () and []
dd_big_endian   dd 0x9ABCDEF0           ; that's why duplicate macro with struc    
Don't forget about ? and x dup (y) as arguments, that complicate things much more. Wink


Hmm, so [] allows more than one arguments, and () allows expression such as (0x1200+0x34). And does the struc allows one to declare stuff without the colon?
Post 09 Nov 2008, 03:15
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Nov 2008, 08:09
wht36,

You're almost correct. Expressions are allowed even without (), but the result is rather unexpected (at a first glance).
Post 09 Nov 2008, 08:09
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20300
Location: In your JS exploiting you and your system
revolution 09 Nov 2008, 08:31
The expressions are evaluated according the to normal rules after the parameter replacement has been applied.
Code:
macro something parameter {
  dd parameter*4
}

something 1  ;generates "dd 1*4"
something 2+3  ;generates dd 2+3*4    
Hence the brackets to force the internal evaluation of the parameter before any external operations are applied.
Post 09 Nov 2008, 08:31
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Nov 2008, 09:07
revolution,

By the way, what do you think about big-endian dsomethings? In my opinion, macro should have the same name as some built-in feature only if it behaves exactly the same in documented situations (I mean, same syntax and semantics, that's what I was trying to implement in big_endian macro), with exact indication of extended syntax/semantics (hence it's prefix macro). That's the example:
Code:
        cmp     [number], 0x78563412
;dd is redefined somewhere above to big-endian dd
number  dd      0x12345678    
is confusing much more than
Code:
        cmp     [number], 0x78563412
;big_endian defined, dd left alone
number big_endian dd 0x12345678    
unless Tomasz decide to add macro functions to fasm. Wink
Post 09 Nov 2008, 09:07
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20300
Location: In your JS exploiting you and your system
revolution 09 Nov 2008, 09:46
I would not personally use dd for a BE version of the normal dd. It would seem to me to be far too confusing and prone to errors.

The choice of name is arbitrary and is generally influenced by the authors own biases. So it really doesn't matter, but I am sure most would agree that names that appear more meaningful would be preferable to completely random names.

Another option is to make separate macros for each size. be_dq, be_dd, be_dw or, depending upon one's personal preference dq_be, dd_be, dw_be.
Post 09 Nov 2008, 09:46
View user's profile Send private message Visit poster's website Reply with quote
wht36



Joined: 18 Sep 2005
Posts: 106
wht36 09 Nov 2008, 11:40
While testing baldr's macros, I found that it does not accept floating point numbers (error: invalid value), and the problem appears to be due to shr. So is there a way to do it without using shr? I have tried using the other macro, but I think I'm not using it right (generate some strange output...). Nevertheless, I derived a rather ugly macro from it that works with floats as well.

Code:
macro dd [op] {
 local .dd,.a,.b
 .dd: dd op
 load .a byte from .dd
 load .b byte from .dd+3
 store byte .b at .dd
 store byte .a at .dd+3
 load .a byte from .dd+1
 load .b byte from .dd+2
 store byte .b at .dd+1
 store byte .a at .dd+2
 }

macro dw [op] {
 local .dw,.a,.b
 .dw:  dw op
 load .a byte from .dw
 load .b byte from .dw+1
 store byte .b at .dw
 store byte .a at .dw+1
 }
    
Post 09 Nov 2008, 11:40
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 09 Nov 2008, 12:17
Simpler modification that fixes this problem:
Code:
macro dd op {
   local value
   value = dword op
   dd 0 or ((value and 0FF000000h) shr 24) or \
           ((value and 000FF0000h) shr  8) or \
           ((value and 00000FF00h) shl  8) or \
           ((value and 0000000FFh) shl 24)
}    
Post 09 Nov 2008, 12:17
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Nov 2008, 12:22
wht36,

For integral type, value and representation essentially the same, that's why you can simply split value in parts with shift/and, then combine them together in another order. Floating point values aren't so straightforward.

See big_endian macro above, it's much more generic (but idea is the same as yours). What kind of strange output it generates? rept {} and repeat… end repeat are leftovers from test, you may safely delete them from source. Wink
Post 09 Nov 2008, 12:22
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Nov 2008, 12:28
LocoDelAssembly,

I'd remembered why I didn't use "." in struc definition: that way you'll end up with data definition directive, not macro expansion. Wink
Post 09 Nov 2008, 12:28
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8351
Location: Kraków, Poland
Tomasz Grysztar 09 Nov 2008, 12:42
baldr wrote:
I'd remembered why I didn't use "." in struc definition: that way you'll end up with data definition directive, not macro expansion. Wink

You should have used it this way:
Code:
label . dword    

By not using "." you cause the size-less label to be generated.
Post 09 Nov 2008, 12:42
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: 20300
Location: In your JS exploiting you and your system
revolution 09 Nov 2008, 13:11
baldr wrote:
LocoDelAssembly,

I'd remembered why I didn't use "." in struc definition: that way you'll end up with data definition directive, not macro expansion. Wink
Not that it matters here, but you can also use the colon to force the macro expansion.
Code:
.: dd something    
Post 09 Nov 2008, 13:11
View user's profile Send private message Visit poster's website Reply with quote
wht36



Joined: 18 Sep 2005
Posts: 106
wht36 09 Nov 2008, 13:12
Tomasz Grysztar wrote:
Simpler modification that fixes this problem:
Code:
macro dd op {
   local value
   value = dword op
   dd 0 or ((value and 0FF000000h) shr 24) or \
           ((value and 000FF0000h) shr  8) or \
           ((value and 00000FF00h) shl  8) or \
           ((value and 0000000FFh) shl 24)
}    

Ah... typecasting. Of course!

baldr wrote:
For integral type, value and representation essentially the same, that's why you can simply split value in parts with shift/and, then combine them together in another order. Floating point values aren't so straightforward.

See big_endian macro above, it's much more generic (but idea is the same as yours). What kind of strange output it generates? rept {} and repeat… end repeat are leftovers from test, you may safely delete them from source.

I am not sure but the output is expanded with zeroes. But perhaps it's because I used
Code:
macro dd [op] { big_endian dd,op }.    
Post 09 Nov 2008, 13:12
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 09 Nov 2008, 13:26
Tomasz Grysztar,

Is there a reason for that
Code:
fp_d = dword 1.0
        dd      fp_d    
works, but
Code:
        dd      dword 1.0    
give "invalid argument" error? Something in expression evaluation logic? I thought these code fragments are almost equivalent…

I'm trying to devise some evil scheme Wink to pass struc big_endian's label to macro big_endian, of no avail yet. struc and dds are so much context-sensitive…

revolution,

That label will be typeless, as Tomasz noted.

wht36,

Comma between dd and [op] is the source of problem. match datadef_directive val,dd will not match and macro will expand to nothing. I didn't comment macro usage, my fault. It's used as prefix for data definition directive, like
Code:
big_endian dd 1.0; same effect as db 0x3F, 0x80, 0, 0    
Your macro definition use implicit forward, may explicit common be of some use?
Post 09 Nov 2008, 13:26
View user's profile Send private message 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.