flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > Suggestion: eqtype label

Author
Thread Post new topic Reply to topic
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal 30 Mar 2014, 16:06
Hi. My suggestion is that eqtype should work with the label keyword to differentiate between numeric constants: eqtype label. Example:
Code:
a:     ; label
b dd 0 ; label
c=1    ; constant

if a eqtype label
 'true, is label'
end if

if c eqtype 0          ; true, is number
 if c eqtype label     ; but not label/name/memory
  'false, is constant'
 end if
end if    
Without such feature, there is no safe way to create HL variables with type/size/sign information and perform error checking in macro languages. No good way to tell the difference between numbers and labels.
Post 30 Mar 2014, 16:06
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 767
tthsqe 30 Mar 2014, 18:45
I am no expect on eqtype, but can't you do this by making label a label itself?

Code:
label: dq ?

if a eqtype label
 ...
end if
    
Post 30 Mar 2014, 18:45
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr 31 Mar 2014, 11:19
tthsqe,

No, you can't use reserved word as a symbol.

Actually eqtype operator accepts directive names as valid operand(s), though the result is somewhat different: it checks whether both operands are directive names.

----8<----
m3ntal,

eqtype is the one of if directive operators that gets preevaluated by the parser, before the assembly stage occurs (hence no type information is available yet; in fact, the assembler simply won't see the falsy block contents provided that the parser has determined the if condition beforehand).
Post 31 Mar 2014, 11:19
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 31 Mar 2014, 17:58
m3ntal
What would you say about the following cases?
Code:
a:
x = a        ;a label or a variable?
y = 0
label b at y ;a label or a variable?    

And if you just formally say, that everything defined by the equality sign is a variable, then consider, how the above cases would affect the type checking, you wanna implement.

Btw. the only functional difference between a label and a constant — i.e. something you call variable, that is never redefined — is that constants do not become prefixes for labels/variables starting with a single dot. Do you really want to use this subtle difference as a conclusive factor for your type or whatever error checking?

_________________
Faith is a superposition of knowledge and fallacy
Post 31 Mar 2014, 17:58
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal 01 Apr 2014, 05:32
baldr: I understand how it works currently and the classification of symbols, but I think there should be an exception for eqtype label OR some way to differentiate between numbers and labels.

l_inc: What's the difference? A variable will have a standard label (a: or label a or a dd 0) defined for it. Not all labels are the same. As you know, there is a difference between and a: dd 0 and a dd 0 which has a known size. That's why this works with no type cast: mov [a], 1. FASM knows the difference internally. Another difference is that if defined name works for labels but not for numerics and is the current method I'm using (name$#type). Please don't say something is impossible just because you can't think of a way to do it.
Quote:
if you just formally say, that everything defined by the equality sign is a variable... only functional difference between a label and a constant — i.e. something you call variable, that is never redefined...
That's ridiculous. None of those are variables. A variable is a label with type/size/sign associated with it. Try making a compiler or assembler then you will understand this.

I'm working on a preprocessor for my ARM assembler and it's getting pretty advanced. It does 3-4 scans/passes to supports numeric constants and labels with forward references. It uses the # prefix for numeric constants - # a=0,b=1,c=2 - to eliminate any conflict. It is both assembler AND HL compiler. For example, here is how I create labels:
Code:
; create new define of name and value

function create.define, name, value
  alias name=v1, value=v2,\
   p=v3, i=v4, n=v5
  . name=a1, value=a2
  try verify.name name
  . p=defines.n, (u32) n=*p  ; # defines++
  . i=n, n++, (u32) *p=n
  . p=define.names
  . p=p+(i<<5)               ; &define.names[i*32]
  text.copy p, name
  . p=define.values
  . p=p+(i<<2)               ; define.values[i*4]
  . (u32) *p=value
endf 1

; create label at ip (a: .x:)

function create.label, name
  alias name=v1,\
   value=v2, p=v3, c=v4
  . name=a1, value=a2
  . p=@ip, (u32) value=*p
  . (u8) c=*name
  .if c=2Eh ; '.'
    text.prefix name, label.prefix
  .else
    text.copy label.prefix, name
  .end
  create.define name, value
endf    


Last edited by m3ntal on 19 May 2014, 18:08; edited 1 time in total
Post 01 Apr 2014, 05:32
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 01 Apr 2014, 08:06
m3ntal
First of all, when I said variables, I was referring to the compile-time variables as well as compile-time constants. Therefore most part of your answer has nothing to do with my comment.
Quote:
Another difference is that if defined name works for labels but not for numerics and is the current method I'm using (name$#type).

I assume here, when you say "numerics" you mean the compile-time variables and compile-time constants. In this context I don't think the remark "another difference" makes any sense, because what you was referring to before were run-time variables. Besides the statement is just wrong, because defined works for both "numerics" and labels.
Quote:
Please don't say something is impossible just because you can't think of a way to do it.

I have no idea, what you're talking about, cause I didn't say something is impossible. I said, that equtype label made no sense, because the only difference between a label and a compile-time constant is being able to become a prefix.

_________________
Faith is a superposition of knowledge and fallacy
Post 01 Apr 2014, 08:06
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal 01 Apr 2014, 14:24
l_inc: We use different terminology.

FASM should have the ability to distinguish numbers from labels for HL variables, type safety and error checking. I can do this in my preprocessor by assigning a type to each defined name (constant='n', label='l', variable='v', etc).

An example of if defined:
Code:
macro create.variable a {
 a: dd 0
 name.#a equ a
 type.#a='i'
 size.#a=32
 sign.#a=1
}

macro is.variable a {
 if defined name.#a
  'Yes'
 end if
}

create.variable abc

is.variable 123 ; false
is.variable abc ; true, 'Yes'    
is.variable abc is true but is.variable 123 is false. Only the second if defined is true. I hate using hacks like this which causes an error with 'c' constants (is.variable 'c').

Why should I respect the opinions of those who do not make programs?


Last edited by m3ntal on 19 May 2014, 18:09; edited 1 time in total
Post 01 Apr 2014, 14:24
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 01 Apr 2014, 14:37
m3ntal wrote:
FASM should have the ability to distinguish numbers from labels for HL variables, type safety and error checking.
I'm not so sure that "should" is the correct word here. While some here may want such a thing I don't think it is fair to say it "should" support it.
Post 01 Apr 2014, 14:37
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 01 Apr 2014, 15:36
m3ntal
Quote:
FASM should have the ability to distinguish numbers from labels

Any number can functionally be a label as well. The difference is in the programmers head only.
Quote:
for HL variables, type safety and error checking

Your implementation of variables does not seem to need the differentiation.
Quote:
I hate using hacks like this which causes an error with 'c' constants

That's not a hack. That's just a bug in your code. If you expect a string to be passed as an argument to your macro, then you also should check if it's a string:
Code:
if ~ '' eqtype a & defined name.#a    

If you expect numeric expressions to be passed to your macro, then also add a preliminary check for multiple tokens with match.
Quote:
Why should I respect the opinions of those who do not make programs?

Quite an absurd attempt to be offensive. What you shouldn't do anyway is to make conclusions based on unverified assumptions.

_________________
Faith is a superposition of knowledge and fallacy
Post 01 Apr 2014, 15:36
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal 03 Apr 2014, 08:31
Quote:
I'm not so sure that "should" is the correct word here.
I really don't care either way, not enough to argue. I have my own development utilities and can implement whatever I desire.
Quote:
Any number can functionally be a label as well. The difference is in the programmers head only.
It is true that a label equates to a number, and from that perspective, there is no difference, but a constant is not necessarily an address. Label=Address/Offset. Constant=Any number. In HL compilers (and macro languages), there is a distinction. Assembler is unforgiving and has no type safety. One slight mistake and it crashes.
Quote:
That's not a hack. That's just a bug in your code.
That's the simplest example of variables and is not exactly how I do it. Your check to ensure it's not '' makes it even more of a "hack" though it may solve the problem with '' constants.
Quote:
What you shouldn't do anyway is to make conclusions based on unverified assumptions.
Well, I see no evidence, no reason to believe. Never seen any assembler code from you, not to mention one program. By the way, I learned what I know about FASM by studying Tomasz's code.

My latest macro syntax:
Code:
; convert text to unsigned 32BIT integer

function t2u, t
  alias t=v1,\
   c=v2, n=v3
  . t=a1, (u8) c=*t
  .if c=30h           ; skip preceding
    .while c=30h      ; '0's...
      . (u8) c=*t++
    .endw
    . t--
  .end
  .if c=0             ; 0 value?
    return 0
  .end
  . n=0
  .forever
    . (u8) c=*t++
    .if c=0
      return n
    .end
    . n+(n<<2), n+n   ; n=n*10+*t++-'0'
    . n-30h, n+c
  .endfv
endf n    
Note: Some so-called HL syntaxes - conditional execution, if-then-else (it) blocks and pointer arithmetic (*p++) - are actually native instructions on ARM (M68k has even more advanced pointer syntaxes). So, the ones who say "Don't use if" or "Don't use *p++" are seeing "assembler" strictly through the lens of a X86-only programmer.
Post 03 Apr 2014, 08:31
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 03 Apr 2014, 09:45
m3ntal
Quote:
Label=Address/Offset. Constant=Any number.

Once again, label in fasm is also any number:
Code:
label a at 123    

Quote:
In HL compilers (and macro languages), there is a distinction. Assembler is unforgiving and has no type safety.

Yes. And yes. And as long as fasm is an assembler there is not much difference between labels and numbers in fasm. You can create the difference in your own HL constructs by implementing those in macros.
Quote:
Well, I see no evidence, no reason to believe

I don't try to teach you religion and I don't announce facts, that have to be believed as is. Read, understand and only then agree or disagree. You don't need to believe, if you're able to think yourself.
Quote:
I learned what I know about FASM by studying Tomasz's code

Now try to guess, why he still didn't appear in your topic.

_________________
Faith is a superposition of knowledge and fallacy
Post 03 Apr 2014, 09:45
View user's profile Send private message Reply with quote
m3ntal



Joined: 08 Dec 2013
Posts: 296
m3ntal 03 Apr 2014, 15:52
Ok, but the typical definition of a label is a name that represents a location/address/offset. Saying that it's a number is vague. What type of number? Technically, everything is a number: opcode, register, mode, etc.
Quote:
Now try to guess, why he still didn't appear in your topic.
... which is good. I'm not wanting responses.
Post 03 Apr 2014, 15:52
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 03 Apr 2014, 16:17
m3ntal wrote:
I'm not wanting responses.
Be careful what you wish for because you might get it.
Post 03 Apr 2014, 16:17
View user's profile Send private message Visit poster's website Reply with quote
shutdownall



Joined: 02 Apr 2010
Posts: 517
Location: Munich
shutdownall 14 Apr 2014, 16:34
l_inc wrote:
m3ntal
Quote:
Label=Address/Offset. Constant=Any number.

Once again, label in fasm is also any number:
Code:
label a at 123    



I don't agree. A label always represents an address. An address can be any number in valid address range. That's the point.

You can not assign a floating point value to a label nor can you use a 64 bit value when using 32 bit (use32) for example.
Post 14 Apr 2014, 16:34
View user's profile Send private message Send e-mail Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 14 Apr 2014, 18:26
shutdownall
First of all, please, note, that the discussion is in the context of fasm. Considering this...
Quote:
An address can be any number in valid address range. That's the point.

The valid address range of a label equals to the valid value range of a numeric constant/variable.
Quote:
You can not assign a floating point value to a label

I cannot do so with numeric constants/variables either.
Quote:
nor can you use a 64 bit value when using 32 bit (use32)

Oh, I can:
Code:
use32

label lbl1 at 0x100000000
label lbl2 at -1

dq lbl1
dq lbl2    

Moreover, I even consider this to be very handy for some use cases. I never checked, if a eip-overlay is possible, but I think the behaviour could be similar to the ip-overlay in 16-bit code. I mean the instructions could be fetched not from eip, but from rip>=2^32 being at the same time in 32 bit mode.

_________________
Faith is a superposition of knowledge and fallacy
Post 14 Apr 2014, 18:26
View user's profile Send private message Reply with quote
shutdownall



Joined: 02 Apr 2010
Posts: 517
Location: Munich
shutdownall 14 Apr 2014, 20:25
Your last example doesn't compile in FASM version 1.71.01 (value out of range).

I don't know about recent changes - anyway I would prefer the correct context.
Naturally every address represents a numeric value - on the other hand not every numeric value represents an address.

An example ?
My dick has 170 mm length - I wouldn't interprete this as a valid address. Razz
Numeric values without a dimension is not more than abstract mathematics - nothing to do with addressing at all.
Post 14 Apr 2014, 20:25
View user's profile Send private message Send e-mail Reply with quote
JohnFound



Joined: 16 Jun 2003
Posts: 3499
Location: Bulgaria
JohnFound 14 Apr 2014, 21:11
shutdownall, 170mm is not so valuable argument. Razz

l_inc is absolutely right here - the addresses are simply numbers. Abstract.

Notice, that CPU operates exactly with numbers (as defined in mathematics). There is no dimensions there. It is the human interpretation what number means.
Post 14 Apr 2014, 21:11
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 14 Apr 2014, 21:29
shutdownall
I can't understand people wittingly using older and buggy versions of software instead of newer and improved ones. The bug was fixed in 1.71.11.
Quote:
I don't know about recent changes - anyway I would prefer the correct context.

The context of use32 defines the code generation mode only. It does not and must not define how numeric calculations (including those with labels) are performed. As I said before, I'm not sure, but I think it might be possible to execute 32 bit code at addresses beyond 2^32, in which case it's very desirable to make sure the compiler knows this and can verify fulfillment of additionally applied restrictions. There's a number of other possible use cases.
Quote:
Naturally every address represents a numeric value - on the other hand not every numeric value represents an address.

You are missing the main difference between low level and high level languages. Low level is more control to the programmer and less control over the programmer. The address semantics of a label in fasm is in the programmer's head only. I as a programmer wanna decide myself if I define a 64 bit label in 32-bit code generation mode context. This might be meaningful and the compiler just can be unaware of that meaningful semantics.
Quote:
My dick has 170 mm length

I don't think you prefer a compiler to tell you "value out of range", because it knows it's 120 mm at most.
Quote:
Numeric values without a dimension is not more than abstract mathematics - nothing to do with addressing at all.

You're again losing the context. It's still fasm. Every number representable in fasm can be (I don't say "is") a valid address. No matter what current code generation mode is.

_________________
Faith is a superposition of knowledge and fallacy
Post 14 Apr 2014, 21:29
View user's profile Send private message Reply with quote
f13nd



Joined: 09 Mar 2018
Posts: 1
f13nd 09 Mar 2018, 20:11
Try to use MODRM field of LEA instruction in virtual space. Good for separate local values/proc arguments with constants.

Code:
macro typetest d {
    if d eqtype DWORD[ebp]
         match a[tail],d \{
              match =DWORD,a\\{display 'DWORD[]',0x0d,0x0a\\}
              match =WORD,a\\{display 'WORD[]',0x0d,0x0a\\}
              match =BYTE,a\\{display 'BYTE[]',0x0d,0x0a\\}\}
    else if d eqtype [ebp]
         match [a],d\{display '[]',0x0d,0x0a\}
    else
         virtual
              lea eax,[d]
              load modrm byte from $$ + 1
         end virtual
         if ((modrm shr 3) and 11111b) or (modrm and 111b) = 00101b
              display 'NUMERIC(MAYBE LABEL)',0x0d,0x0a
         else
              display 'REGISTER-BASED LABEL',0x0d,0x0a
         end if
    end if }
   virtual at 1
    .m1:
   end virtual
   virtual at ebp + 1001
    .m2:
   end virtual
   virtual at edx + ebx*8 + 1000
    .m3:
   end virtual
     typetest .m1       ;NUMERIC(MAYBE LABEL)
     typetest .m2       ;REGISTER-BASED LABEL
     typetest .m3       ;REGISTER-BASED LABEL
     typetest WORD[.m1] ;WORD[]
     typetest [.m2]     ;[]      
Post 09 Mar 2018, 20:11
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.