flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > How to get the address in something passed?

Goto page Previous  1, 2, 3  Next
Author
Thread Post new topic Reply to topic
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 21 Dec 2009, 16:47
I'm thinking of an alternative...

you can use store for this job.

First, count the number of entries on the list, for example, everytime you detect a number is less than a given value, you increment a constant (not symbolic constant)

Code:
rept 1  ; this is for keeping the variables local
{
  local n
  n=0
  macro whatever number
  \{
    if number < 1000
      store dword number at list+n*4
      n=n+1
    end if
  \}
  macro ending  ; you need to put this at the end of the program
  \{
    list_length = n
  \}
}


list dd list_length dup (0)

whatever 5
whatever 6
whatever 1007

ending    
if, however, you want to put the list of numbers at the end of the file, or "after" the 'whatever' macros, you could do this:

keep a symbolic list of all numbers, then you iterate through this list with irps for instance when you want to define the list... and do:
Code:
irps l, list
{
  if l < 1000
    dd l
  end if
}    
Smile


EDIT: example of the latter approach:

Code:
rept 1
{
  local lst
  define lst +  ; start with '+' otherwise match would get skipped
  macro whatever num
  \{
    match x,lst  ; because we restore lst to keep memory down
    \\{
      restore lst
      define lst x num  ; add 'num' to the list
    \\}
  \}
  macro list
  \{
    match +list, lst  ; get the list without the first '+'
    \\{
      irps l, list  ; go through each number (symbol)
      \\\{
        if l < 1000
          dd l
        end if
      \\\}
    \\}
  \}
}


whatever 5
whatever 6
whatever 1007

list    

_________________
Previously known as The_Grey_Beast
Post 21 Dec 2009, 16:47
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 21 Dec 2009, 23:16
Actually you can use a combination of the two versions:

Code:
rept 1
{
  local lst,n
  define lst +
  macro whatever num
  \{
    match x,lst
    \\{
      restore lst
      define lst x num
    \\}
  \}
  macro ending
  \{
    match +list__, lst
    \\{
      n=0
      irps l, list__
      \\\{
        if l < 1000
          store dword l at list+n*4
          n=n+1
        end if
      \\\}
      list_length = n
    \\}
  \}
}


whatever 5

list dd list_length dup (0)

whatever 6
whatever 1007

ending    


I suggest you use this because it's the most flexible and you can put the list anywhere, even between macros used... the 'ending' macro does the job of going through the created list and putting the values in the list.

Also list_length is defined at the end only once, so it is used in the second pass (this uses FASM's multi-pass capabilities).
Post 21 Dec 2009, 23:16
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 22 Dec 2009, 04:06
Thank you! Very Happy


I am using the first way, so that I only need one list (it isn't the value of the operand that I am storing, but rather the address it is at, so I can add the base address to it). With the second one I would need to store both the value and the address it is at, so it would take more memory to compile.




Soon I will have macros for every instruction to make them all relocatable automatically. Very Happy
This really beats putting in the addresses manually.

_________________
Post 22 Dec 2009, 04:06
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 22 Dec 2009, 22:56
ah yes I'm usually not thinking about memory because I never had problems with it or with speed in FASM. Smile

also I agree about doing it automatically, in fact, I love FASM's powerful macro capabilities... since I learned FASM (long time ago) I've never inputted anything manually (like offsets or other calculations).
Post 22 Dec 2009, 22:56
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 23 Dec 2009, 13:37
Azu,

Back to the starting problem: FASM can itself help to extract displacement from address (try this with match Wink):
Code:
macro get_ea_disp addr, disp {
  virtual at 0
    lea eax, addr
    load ModRM byte from 1
    M = (ModRM shr 6) and 3
    if M=1
      load disp byte from $-1
    else if (M=2) | ((M=0) & ((ModRM and 7)=5))
      load disp dword from $-4
    end if
  end virtual
}

; Example:
; ecx is scaled index into array of STRUCT, FIELD1 is array of 8-byte SUBSTRUCTs
; and we need most significant byte of FIELD2
get_ea_disp [array+ecx+STRUCT.FIELD1+edx*8+SUBSTRUCT.FIELD2+3], disp    
Post 23 Dec 2009, 13:37
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 23 Dec 2009, 16:20
But what you used are assembly-time directives not pre-processor like match... he can't build a list with that.

BTW nice trick Wink

_________________
Previously known as The_Grey_Beast
Post 23 Dec 2009, 16:20
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 23 Dec 2009, 18:54
Borsuc,

My solution is based on topic's starting post (anyone remembers it? with ifs and reference to eqtype).


Azu,

Not every imm (and disp in r/m) is relocatable item, right? The best you can do (apart from rewriting entire FASM assembly stage in FASM directives' language Wink) is compile to COFF and parse it for relocations.
Post 23 Dec 2009, 18:54
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 23 Dec 2009, 21:43
baldr wrote:
Azu,

Back to the starting problem: FASM can itself help to extract displacement from address (try this with match Wink):
Code:
macro get_ea_disp addr, disp {
  virtual at 0
    lea eax, addr
    load ModRM byte from 1
    M = (ModRM shr 6) and 3
    if M=1
      load disp byte from $-1
    else if (M=2) | ((M=0) & ((ModRM and 7)=5))
      load disp dword from $-4
    end if
  end virtual
}

; Example:
; ecx is scaled index into array of STRUCT, FIELD1 is array of 8-byte SUBSTRUCTs
; and we need most significant byte of FIELD2
get_ea_disp [array+ecx+STRUCT.FIELD1+edx*8+SUBSTRUCT.FIELD2+3], disp    


Thanks baldr.

I don't need to change offsets into arrays though.

They should be the same wherever the code is located.

Or did I misunderstand your post?


baldr wrote:
Azu,

Not every imm (and disp in r/m) is relocatable item, right? The best you can do (apart from rewriting entire FASM assembly stage in FASM directives' language Wink) is compile to COFF and parse it for relocations.

But if it is COFF then it won't run. Won't I have to manually take additional steps? I want a solution that FASM can do on it's own (which so far Borsuc's way is successful in, although it's more difficult making macros for all instructions than I thought it would be). Or is there a way to keep making my file the way I am now and just have the COFF output into a virtual directive and load the list from there?

_________________
Post 23 Dec 2009, 21:43
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 23 Dec 2009, 22:32
Azu,

That macro extracts 56 from something like dword[56], [ecx+56] or [50+ecx*8+6]. I thought this is what you're trying to accomplish. The example was given to demonstrate it's ability to handle complex address expressions (indeed FASM handles them Wink).

Somewhere in the thread you'd mentioned automatic relocation, thus I deduced that you're going to create list of all relocatable items in code. Not a simple task, I think.

Maybe if you provide more details about your problem...
Post 23 Dec 2009, 22:32
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 23 Dec 2009, 23:18
Thanks.

Yes, that is what I am trying to do. I want to store their addresses in a list that I can loop through and add it to.

The method you posted will be helpful for making sure the memory operands are within the right range. Using just Borsuc's way I couldn't check ones with register offsets (or at least not very easily). I still need to find a way to tell what address should be added to the list though. With the different offsets the size of the instruction is different so what I'm doing now is trying to special case all the ones I use.
Post 23 Dec 2009, 23:18
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2465
Location: Bucharest, Romania
Borsuc 23 Dec 2009, 23:36
Just wondering (nothing to do with either method) do you modify the instruction offsets at runtime or...?
Post 23 Dec 2009, 23:36
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 24 Dec 2009, 00:47
Azu,

FASM provides data fixups directive which inserts base relocation table into output file.

Warning: FASM also fills corresponding entry in PE data directory, so if you tamper that table, PE probably will be garbled or won't load at all. virtual won't help either, relocation table will be absent in PE but directory entry still filled. This is applicable only in case loader needs that table.
Post 24 Dec 2009, 00:47
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 24 Dec 2009, 08:53
fasm really lacks a feature that would allow to manually generate relocation with "format binary". I was planning such thing almost since the begining, but I was never able to come out with some nice syntax solution for it.
Post 24 Dec 2009, 08:53
View user's profile Send private message Visit poster's website Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 24 Dec 2009, 08:57
Borsuc wrote:
Just wondering (nothing to do with either method) do you modify the instruction offsets at runtime or...?
Yes.
I have a block of code that needs to run anywhere and it was really annoying making a list by hand of the addresses that needed to be modified.

baldr wrote:
Azu,

FASM provides data fixups directive which inserts base relocation table into output file.

Warning: FASM also fills corresponding entry in PE data directory, so if you tamper that table, PE probably will be garbled or won't load at all. virtual won't help either, relocation table will be absent in PE but directory entry still filled. This is applicable only in case loader needs that table.
Is there a way to output it somewhere without using the section macro? And does it give a list of the addresses that need changed or just the start of the instruction? I need the former, and it's tricky making macros to do it since one instruction can be so many different lengths..

Tomasz Grysztar wrote:
fasm really lacks a feature that would allow to manually generate relocation with "format binary". I was planning such thing almost since the begining, but I was never able to come out with some nice syntax solution for it.

I don't use any of the format macros, I have my own macros to make the file. So I can make it smaller. Very Happy
You say there isn't a way to do it with format so that means there is a way to do it without? Please tell me how..

p.s.
Will it work for stuff in virtual directives in my block of code? Or I will have to keep handling those myself? Like e.g.
Code:
code that doesn't need relocated
beginPIC:
some code that needs relocated
virtual at somewhere else
some code that references data and/or jmps to code in between beginPIC and endPIC, and thus needs relocated
some load directives
end virtual
endPIC:
code that doesn't need relocated    



Will it work for this scenario?

_________________
Post 24 Dec 2009, 08:57
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 24 Dec 2009, 15:28
Quote:

format macros

format macros? Take a second look to the manual.
Post 24 Dec 2009, 15:28
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 24 Dec 2009, 16:52
Azu,

data fixups/end data generates standard PE base relocation table. It has simple format, refer to PE and COFF specification.

Position-independent code is, by definition, position-independent, isn't it?

Relocatable items in virtual block? I'd tested that, no way.

Base relocations do not apply to your case: they're used to relocate image as a whole (thus the name -- base relocations).

It looks more like linking two objects together: you'll need IMAGE_REL_I386_DIR32 (for objects' relocation and linking imm32/disp32) and IMAGE_REL_I386_REL32 (for relative inter-module branch/call instructions) type relocations.


Tomasz Grysztar,

I'd skimmed FAS specification (quite old, 2008-11-16), fixups didn't appear there, right?
Post 24 Dec 2009, 16:52
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 24 Dec 2009, 21:37
baldr wrote:
Relocatable items in virtual block? I'd tested that, no way.
Thanks. I'll just keep doing it with macros then. No sense trying to implement both ways.

_________________
Post 24 Dec 2009, 21:37
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 24 Dec 2009, 21:50
Azu,

Why don't you compile both chunks as modules to COFF and parse them for code/fixups?

Address expressions are evil, it's almost impossible to parse them appropriately without type information.
Post 24 Dec 2009, 21:50
View user's profile Send private message Reply with quote
Azu



Joined: 16 Dec 2008
Posts: 1159
Azu 24 Dec 2009, 22:04
baldr wrote:
Azu,

Why don't you compile both chunks as modules to COFF and parse them for code/fixups?

Because I'd have to compile 3 separate files and manually dig through two of them to get the list of addresses? I find it so much nicer to just press a key and have it be compiled and working just like that. I really like convenience. I'm also planning to make edit and continue functionality for the same reason.

baldr wrote:
Address expressions are evil, it's almost impossible to parse them appropriately without type information.
Borsuc's suggestion to use match solved this. The "any" isn't just there for no reason; it tells me what type it is (byte, word, dword, fword, etc). Very Happy

_________________
Post 24 Dec 2009, 22:04
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger MSN Messenger ICQ Number Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 24 Dec 2009, 22:10
Azu,

OK, how do you decide whether arbitrary expression is relocatable?
Post 24 Dec 2009, 22:10
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3  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.