flat assembler
Message board for the users of flat assembler.

Index > Main > Understanding $ with EQU and =

Author
Thread Post new topic Reply to topic
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 07 Sep 2014, 14:25
Hi,

I guess I should know this, but apparently I do not. I was using this code:

Code:
E820Buffer:          times 24 db 0
E820BufferLength     equ ($ - E820Buffer)    


I assumed 'E820BufferLength' would equal 24, but when I reviewed it, because I ran into problem with a 'real machine' versus a virtual one(s), it revealed it was 250. I had assumed that '$' meant the current location and hence the end of the E820Buffer, would be a length of 24 bytes, but every time it compiled it compiled to 250. To force the size, I had to do this code:
Code:
E820Buffer:          times 24 db 0
E820BufferEnd:
E820BufferLength     equ (E820BufferEnd - E820Buffer)    


Can someone explain where I'm not understanding?

Smiddy
Post 07 Sep 2014, 14:25
View user's profile Send private message Reply with quote
badc0de02



Joined: 25 Nov 2013
Posts: 215
Location: %x
badc0de02 07 Sep 2014, 14:54
weird...

hmm i think there is a bug somewhere

im using this to simulate the situation because you only show a part of your code:
Code:
org 7c00h
E820Buffer:          times 24 db 0
E820BufferLength     db ($ - E820Buffer)     

out put in hex:
Code:
00000000000000000000000000000000000000000000000018    


output in decimal: 24
no problem

quite the same with that other way

i think you have a bug in your code.
or it is a bug in flatassembler
Post 07 Sep 2014, 14:54
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 07 Sep 2014, 15:36
Well, I wonder if the 'equ' is part of the issue. Unfortunately I don't have time to relook at it presently. It must be within the usage of locale boundary difference, perhaps? However that doesn't make sense either, since they essentially are saying the very same thing.

I won't get an opportunity to re-look at it for a few days unfortunately. Sad
Post 07 Sep 2014, 15:36
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 07 Sep 2014, 15:39
badc0de02 wrote:
...i think you have a bug in your code.
or it is a bug in flatassembler
Yep, I think so...but which, and where? LOL!

I'll post the rest of the code snippets later.

Smiddy
Post 07 Sep 2014, 15:39
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 07 Sep 2014, 15:52
smiddy
Quote:
Well, I wonder if the 'equ' is part of the issue

It is. equ is a preprocessor directive and $ is an assembly time constant/variable. This means, that the preprocessing time constant E820BufferLength is expanded long before $ is recognized. Consider the following code fragment:
Code:
E820Buffer:          times 24 db 0 
E820BufferLength     equ ($ - E820Buffer)
rb 0x100
dd E820BufferLength    

Now consider what the assembler will see after the preprocessing stage:
Code:
E820Buffer: times 24 db 0
rb 0x100
dd ($ - E820Buffer)    

Would you expect the last dword to contain 24? Or maybe something else?

_________________
Faith is a superposition of knowledge and fallacy
Post 07 Sep 2014, 15:52
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 07 Sep 2014, 19:39
E820Buffer: times 24 db 0
E820BufferLength = ($ - E820Buffer)
Post 07 Sep 2014, 19:39
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 07 Sep 2014, 22:41
l_inc wrote:
smiddy
Quote:
Well, I wonder if the 'equ' is part of the issue

It is. equ is a preprocessor directive and $ is an assembly time constant/variable. This means, that the preprocessing time constant E820BufferLength is expanded long before $ is recognized. Consider the following code fragment:
Code:
E820Buffer:          times 24 db 0 
E820BufferLength     equ ($ - E820Buffer)
rb 0x100
dd E820BufferLength    

Now consider what the assembler will see after the preprocessing stage:
Code:
E820Buffer: times 24 db 0
rb 0x100
dd ($ - E820Buffer)    

Would you expect the last dword to contain 24? Or maybe something else?


rb would reserve bytes elsewhere, especially if you declare a data (this is the wrong verbiage) a data segment, somewhere else. So I don't really know.
Post 07 Sep 2014, 22:41
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 07 Sep 2014, 22:41
typedef wrote:
E820Buffer: times 24 db 0
E820BufferLength = ($ - E820Buffer)
I'll give the equals sign a shot, thanks!
Post 07 Sep 2014, 22:41
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 07 Sep 2014, 22:58
smiddy
Quote:
rb would reserve bytes elsewhere

Oh, I didn't expect your answer to be that much wrong. There is no such thing as "data segment" for fasm (1). fasm does not differentiate data and code at all. rb reserves bytes at the very same location where it appears in the listing. In my example rb 0x100 is effectively the same as times 0x100 db 0 . So if you are for some reason more familiar with db you can consider my example as follows:
Code:
E820Buffer: times 24 db 0 
times 0x100 db 0
dd ($ - E820Buffer)    


(1) Don't misunderstand me here. fasm does support data and code specification for corresponding executable file formats, but this specification does not make any semantical difference for the compiler: you can put both wherever you want and everything will be put into the resulting file in the same order it appears in the listing. Hence the name "flat assembler".

_________________
Faith is a superposition of knowledge and fallacy
Post 07 Sep 2014, 22:58
View user's profile Send private message Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 08 Sep 2014, 02:40
When I started using "flat assembler" was before rx (where x is any of the data type declarations) and never went to any length of study or use them. I did know they were 'reserved' however, but expected them not to be "inline" or "at the very locale" as were they exist in the code, that does make sense though. Does that just mean they are not initialized to any value, and they use what ever is there in those memory locales?

So the question is, when E820BufferLength is recognized first, and then it goes back and assigns the EQU, why doesn't it assign the correct value? Is your point that length is aligned to some boundary value? If so, how does one turn that off boundary alignments?

Is there a difference between '=' and 'EQU'? I assume '=' works, I need to go back and try it. Unfortunately that will be a while.
Post 08 Sep 2014, 02:40
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 08 Sep 2014, 04:06
smiddy wrote:
Is there a difference between '=' and 'EQU'? I assume '=' works, I need to go back and try it. Unfortunately that will be a while.
Indeed there is. I should check the manual to get my facts straight, but my understanding is that EQU is merely a literal string replacement directive, whereas = is the conventional mathematical replacement operator. So you definitely want the latter here, to perform the subtraction of the specified label values.
So this topic should really be renamed to "Understanding EQU and =" Wink

_________________
FAMOS - the first memory operating system
Post 08 Sep 2014, 04:06
View user's profile Send private message Visit poster's website Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 08 Sep 2014, 11:02
Maybe neville, but if I do this:
Code:
E820Buffer:          times 24 db 0 
E820BufferLength     equ 24    
I get what I expect, until after I do this:
Code:
E820Buffer:          times 24 db 0 
E820BufferLength     equ ($ - E820Buffer)    
I get unexpected results. I want to know what to expect, and why.
Post 08 Sep 2014, 11:02
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 08 Sep 2014, 12:02
smiddy
Quote:
Does that just mean they are not initialized to any value

Yes and no. The memory you get from rx is de facto set to zero (same as dx ?). It is however marked as uninitialized. Practically this means that this memory will not become a part of the compiled executable in some cases such as at the end of a file and at the end of a section. A bit different case are macros, that make use of the "uninitialized" semantics. E.g., procedure macros interpret uninitialized data definition directives in a locals block as stack space allocation, in which case you in fact will get whatever it was in the stack before.
Quote:
So the question is, when E820BufferLength is recognized first, and then it goes back and assigns the EQU, why doesn't it assign the correct value?

equ is recognized first and defines E820BufferLength. The $ is however not recognized yet. Then E820BufferLength is recognized, as it was defined by equ. It's correct value is not the result of the calculation but the whole sequence of tokens ($ - E820Buffer). This sequence of tokens is put at the location of E820BufferLength and is then evaluated at that location. As the value of $ is location dependent, you will get different values of the expression ($ - E820Buffer) depending on where you use E820BufferLength and completely independent on where you define E820BufferLength with the equ directive.
Quote:
Is your point that length is aligned to some boundary value?

No. Absolutely not.
Quote:
Is there a difference between '=' and 'EQU'?

neville has already pointed out that difference: equ defines a symbol for further symbolic substitution, and the equality sign induces actual calculation of an expression following it. But it is also important to remember that equ and everything defined by it is processed at the preprocessing stage. $ is meaningless at this early stage and cannot be evaluated. The equality sign is processed during the assembly stages, when $ already can be evaluated as current address.

_________________
Faith is a superposition of knowledge and fallacy
Post 08 Sep 2014, 12:02
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20451
Location: In your JS exploiting you and your system
revolution 08 Sep 2014, 12:37
Perhaps you can see the difference here:
Code:
E820Buffer: times 0x24 db 0
E820BufferLength     equ ($ - E820Buffer)
E820BufferLength2    = ($ - E820Buffer)
dd ($ - E820Buffer) ;<---- places 0x00000024
dd ($ - E820Buffer) ;<---- places 0x00000028
dd ($ - E820Buffer) ;<---- places 0x0000002c
dd E820BufferLength ;<---- places 0x00000030
dd E820BufferLength2;<---- places 0x00000024    
Post 08 Sep 2014, 12:37
View user's profile Send private message Visit poster's website Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 08 Sep 2014, 17:00
Thanks, now I get it (I think): with EQU and $, the $ defines 'where' it is being used (ala E820BufferLength used well into my code, get evaluated there), not the location in the ASM file. I will use = instead.
Post 08 Sep 2014, 17:00
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 08 Sep 2014, 17:13
$.....Current address/offset
EQUATE(s).....same as #define C/C++
=.....Evaluate expression then assign result to
Post 08 Sep 2014, 17:13
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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.