Pages: 1
|
 |
|
Author
|
Topic: Making sense of conditionals (Read 2313 times)
|
|
|
Chuck Adams
Contributor
Jr. Member
  
Karma: +0/-0
Offline
Posts: 24
|
Also, these appear to be the short jump forms of the conditionals, which I understand have problems with longer words where the branch target is too far away ... I looked in reva and it was using the long forms (basically adding $10 to each and prepending a $of byte). I remember this coming up a while back, and am wondering if the compiler somehow backpatches conditionals if the branch target is too far removed?
Just want to figure out the basics first tho
|
|
|
|
|
Logged
|
|
|
|
Charles Childers
Administrator
Sr. Member
    
Karma: +2/-0
Offline
Posts: 745
|
: (if) $063b 2, $adad 2, 1, here 0 1, ;
First off, I can't really figure out what that's doing, which probably explains my confusion for the next words.
This compiles the following code into the definition:
cmp eax, [esi] lodsd ; drop lodsd ; drop
This is followed by the conditional jump opcode (passed on the stack.) The here 0 1, leaves the address of the jump offset on the stack and allocates space for it. then will replace the contents of the offset with the correct value.
Basically, it's just a factored out word shared by the common conditionals.
: <if $7e x: (if) ; : >if $7d x: (if) ;
This is what confuses me. $7E is JLE and $7D is JGE. Not reversed, so I must assume it's subtracting them in the reverse order I was thinking. I sort of figured this out while writing this. But what I don't really get then is why it's JLE/JGE and not JL/JG? Here's an example of why this was done:
: foo <if ." true" cr ;then ." false" cr ; 1 2 foo 2 1 foo 1 1 foo
Compare the results with these (using JL/JG):
macro : <if $7c x: (if) ; : >if $7f x: (if) ; forth : foo <if ." true" cr ;then ." false" cr ; 1 2 foo 2 1 foo 1 1 foo
For 1 1 foo it should display false since 1 is obviously not less than itself.
: ?if $72 1, here 0 1, ;
$72 is JC, makes perfect sense. Again the here 0 1, construct ... I don't quite understand. As before, this inlines to:
jc <offset>
The address (here) is passed on the stack to then to fix up.
: then dup here swap - 1- swap c! $90 1, ;
if is perfectly straightforward, and more asm in then. I kind of lack the ASM debugging skill to see how it works .. consequence of being a perl/python/lisp hacker for so long. I know most of the inlined asm is documented somewhere here... then has the job of patching up the offsets provided by the various conditionals. It determines the current address in the heap, then the difference between the two. I don't recall exactly why the 1- was needed offhand. I'll check up on that again. The assembly $90 1, compiles in a nop at the then point to make sure that tail call elimination is handled properly (forces a compile of a ret instruction if no calls follow the then). It's easily the most complex word in the conditionals.
could it perhaps be merged into some comments in core.f? Would including the assembly listings in the glossary file be enough? I'm quite willing to do that.
|
|
|
|
|
Logged
|
|
|
|
|
|
Chuck Adams
Contributor
Jr. Member
  
Karma: +0/-0
Offline
Posts: 24
|
Aha, it makes sense now ..
|
|
|
|
|
Logged
|
|
|
|
|
|
Pages: 1
|
|
|
|
|