Moderators: EDS50, cgrey8, 2Shaker, Jon 94GT
Inline parameters(arguments)
What are they? They are bytes in the code stream that aren't code. They need directives in the dir file of the BL disassembler so it knows they aren't code and then it needs a code directive to restart disassembling code.
This begs 2 questions
1 How do I find them?
2 What does the data that isn't code mean?
People have asked before "Why did those morons do it that way?" Please take that to another thread.
You find them by knowing that they are probably there in routines that will always be there.
the always there routines are
1D (one dimension)
function lookup ---- in all combinations of signed in and out, and that in byte size and word size
2D table lookup in byte size only in EEC-IV, signed and unsigned output
ROLAV routines
And some more.
You also find them by looking for particular code signatures.
A call instruction is a jump that knows how to get back to the instruction after the call. It does that by placing
the address to go back to on the stack. that's where the return instruction gets it from.
If a routine knows that it will be getting inline parameters, then it looks on the stack, takes its parameters off there, and points the stack after the parameters it wanted so the ret instruction goes back to the right places.
this manipulation of the stack pointer has a code signature that you will understand if you manage to stay with us.
And you'll need to recognize it, or at least recognize that something fishy is going on, in order to deal with inline parameters that are in routines that may not be "always there".
So that's it, a simple way to find some, and a definitive way to find all of them.
As to what they mean, for that we'll need to understand the assembly instructions and some of Ford's conventions.
This begs 2 questions
1 How do I find them?
2 What does the data that isn't code mean?
People have asked before "Why did those morons do it that way?" Please take that to another thread.
You find them by knowing that they are probably there in routines that will always be there.
the always there routines are
1D (one dimension)
function lookup ---- in all combinations of signed in and out, and that in byte size and word size
2D table lookup in byte size only in EEC-IV, signed and unsigned output
ROLAV routines
And some more.
You also find them by looking for particular code signatures.
A call instruction is a jump that knows how to get back to the instruction after the call. It does that by placing
the address to go back to on the stack. that's where the return instruction gets it from.
If a routine knows that it will be getting inline parameters, then it looks on the stack, takes its parameters off there, and points the stack after the parameters it wanted so the ret instruction goes back to the right places.
this manipulation of the stack pointer has a code signature that you will understand if you manage to stay with us.
And you'll need to recognize it, or at least recognize that something fishy is going on, in order to deal with inline parameters that are in routines that may not be "always there".
So that's it, a simple way to find some, and a definitive way to find all of them.
As to what they mean, for that we'll need to understand the assembly instructions and some of Ford's conventions.
Re: Inline parameters(arguments)
Hopefully the posts will get moved from "who is disassembling..." thread, but if not, please hop across and read those posts from mpaton jsa, and me amongst the thread.
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler
https://github.com/tvrfan/EEC-IV-disassembler
Re: Inline parameters(arguments)
I thought we might start with the code that is always there, (specifically the 2D table lookup code) and all its friends.
While that code WILL always be there, it won't always have inline parameters.
However they do in HHX0, so we can go from the algorithmic math to the code, and then to the hint I've got for it.
That would be in the other thread, and then we're back here to determine if we do have inline parameters, and if we d, then in one of the threads we'll deal with Ford's ROM addressing conventions, and how that interacts with how the inline parameter bytes are encoded.
And thanks again Sailorbob for feeding me enough fish food to work all this out all those years ago.
Michael
While that code WILL always be there, it won't always have inline parameters.
However they do in HHX0, so we can go from the algorithmic math to the code, and then to the hint I've got for it.
That would be in the other thread, and then we're back here to determine if we do have inline parameters, and if we d, then in one of the threads we'll deal with Ford's ROM addressing conventions, and how that interacts with how the inline parameter bytes are encoded.
And thanks again Sailorbob for feeding me enough fish food to work all this out all those years ago.
Michael
Re: Inline parameters(arguments)
So taking tvrfans example from the other thread. CALL puts 7276 on the stack for RETURN to pick up ? SCALL puts 7281 on the stack for RETURN to pick up ?mpaton wrote:A call instruction is a jump that knows how to get back to the instruction after the call. It does that by placing
the address to go back to on the stack. that's where the return instruction gets it from.
Code: Select all
Sub63:
7273: ef,79,08 call 7aef Sub79();
Code: Select all
7279: 28,12 scall 728d Sub101(); How does a routine know it will get inline parameters ?mpaton wrote:If a routine knows that it will be getting inline parameters, then it looks on the stack, takes its parameters off there, and points the stack after the parameters it wanted so the ret instruction goes back to the right places.
So the stack is seeded with the inline parameters in advance, then somehow a routine knows the stack is seeded with the parameters it requires ?
Is the stack indexed somehow, so routines, CALL & RETURN know what to take ?
OK.mpaton wrote:this manipulation of the stack pointer has a code signature that you will understand if you manage to stay with us.
Last edited by jsa on Sun Oct 18, 2015 12:02 am, edited 1 time in total.
Cheers
John
95 Escort RS Cosworth - CARD QUIK COSY ANTI / GHAJ0
Moates QH & BE
ForDiag
John
95 Escort RS Cosworth - CARD QUIK COSY ANTI / GHAJ0
Moates QH & BE
ForDiag
Re: Inline parameters(arguments)
How about the compromise that I will answer all of this to the best of my ability if you will please move this post to another thread in EECGeeks.jsa wrote:Humour me momentarily please.mpaton wrote: People have asked before "Why did those morons do it that way?" Please take that to another thread.
Thanks,
Michael
Re: Inline parameters(arguments)
YES, When a subroutine is CALLed, the address where it returns to is pushed onto the stack..... Excellent.
so the RET uses the stack to get back to the next instruction after the call.
Next.....
So if there are data parameters after the CALL opcode, where will they be, and how do you get at them ??
so the RET uses the stack to get back to the next instruction after the call.
Next.....
So if there are data parameters after the CALL opcode, where will they be, and how do you get at them ??
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler
https://github.com/tvrfan/EEC-IV-disassembler
-
decipha
Re: Inline parameters(arguments)
if you go through the routine youll see where the stack is popped and scratch register is incremented to get to the parameters after the call
Re: Inline parameters(arguments)
And whilst we are on the 'training' mode, have a look at this snippet from A9L, and tell me what it does......because you really DO need to understand this kind of trick to get deeper into sorting out those damn inline params. Think carefully ..... bragging points to whoever gets this first. [no not mpaton or sailorbob....]decipha wrote:if you go through the routine youll see where the stack is popped and scratch register is incremented to get to the parameters after the call
Code: Select all
3695: cc,38 pop R38 R38 = pop();
3697: cc,3a pop R3a R3a = pop();
3699: b2,3b,3c ldb R3c,[R3a++] R3c = [R3a++];
369c: b2,3b,3d ldb R3d,[R3a++] R3d = [R3a++];
369f: c8,3a push R3a push(R3a);
36a1: c8,38 push R38 push(R38);
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler
https://github.com/tvrfan/EEC-IV-disassembler
- cgrey8
- Administrator
- Posts: 11304
- Joined: Fri Jun 24, 2005 5:54 am
- Location: Acworth, Ga (Metro Atlanta)
- Contact:
Re: Inline parameters(arguments)
I can see what it is doing. Although I don't get why. Just taking a guess, the stack has 2 pointers (38 & 3a) to byte-size values out in memory that this algorithm is loading into registers (3c&3d). Then incrementing the pointers. And putting them back on the stack in the reverse order it got them off. My best guess is this code is a small part of some larger loop that's looking for something and thus will be using the fetched values in 3c&3d. A table lookup operation for interpolating between neighboring cells????
...Always Somethin'
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
Re: Inline parameters(arguments)
Sorry but no..... not the right focus. The WHY is very important. You have the mechanism 'sort of' right, but not enough of the picture.
(Oops, I should say that 3695 is the start of a subroutine)
Clue - This is to do with inline params in subroutines, and belongs in this thread.
Not only the A9L but a lot of bins do this kind of thing.
(Oops, I should say that 3695 is the start of a subroutine)
Clue - This is to do with inline params in subroutines, and belongs in this thread.
Not only the A9L but a lot of bins do this kind of thing.
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler
https://github.com/tvrfan/EEC-IV-disassembler
Re: Inline parameters(arguments)
I doubt much is going to be learned by just guessing, even if you guess correctly.
So let me advise against doing that.
The call and return instructions have been explained above, and the push and pop can come from the microcontroller manual, or just about any microprocessor manual.
So the method should be to draw yourself a picture of the stack, with the values that each stack address contains. Also draw out a picture of he contents of the registers we care about at the moment. Not all of them, just the ones that appear in the instructions.
Do this for just before and just after each instruction in the code fragment that tvrfan has posted.
Start with this instruction that I just made up.
So the first instruction executed in the one at 0x5656, and the next is the one at 0x3695
and write out a picture of the stack contents, and where the stack pointer points, and what the interesting registers contain.
And say what part of the manual leads you to believe this ie show your working.
It may seem harsh, but now the information manuals are available to you, we want to see you work it out. and not guess.
Guessing is quick and easy for you, and says to me "I can't be bothered to work it out, here's a guess to keep you happy, now tell me the answer"
Michael
So let me advise against doing that.
The call and return instructions have been explained above, and the push and pop can come from the microcontroller manual, or just about any microprocessor manual.
So the method should be to draw yourself a picture of the stack, with the values that each stack address contains. Also draw out a picture of he contents of the registers we care about at the moment. Not all of them, just the ones that appear in the instructions.
Do this for just before and just after each instruction in the code fragment that tvrfan has posted.
Start with this instruction that I just made up.
Code: Select all
0x5656 call 3695
0x5659 word $0020
0x565B word $0122
0x565D stb R38,#$0000and write out a picture of the stack contents, and where the stack pointer points, and what the interesting registers contain.
And say what part of the manual leads you to believe this ie show your working.
It may seem harsh, but now the information manuals are available to you, we want to see you work it out. and not guess.
Guessing is quick and easy for you, and says to me "I can't be bothered to work it out, here's a guess to keep you happy, now tell me the answer"
Michael
- cgrey8
- Administrator
- Posts: 11304
- Joined: Fri Jun 24, 2005 5:54 am
- Location: Acworth, Ga (Metro Atlanta)
- Contact:
Re: Inline parameters(arguments)
Ok, that explains more about what it is doing. The CALL pushes a return address to the stack. However because you don't want to return to data, the code using the inline data is increment the pointer pushed by the CALL past the data section. So the RET pops off the stack the correct return address. Was that the point?
...Always Somethin'
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
Re: Inline parameters(arguments)
Yes.....But.....cgrey8 wrote:Ok, that explains more about what it is doing. The CALL pushes a return address to the stack. However because you don't want to return to data, the code using the inline data is increment the pointer pushed by the CALL past the data section. So the RET pops off the stack the correct return address. Was that the point?
From there, if you go back to my code snippet, what does TWO pops therefore do before the increment ?? (and note first pop, last push is not altered).
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler
https://github.com/tvrfan/EEC-IV-disassembler
-
decipha
Re: Inline parameters(arguments)
Ive been checking in every few days to see the progress, I was purposely waiting for this to get a touch more advanced before chiming in so those that can benefit from this the most can
But since you've specifically called me out...
the first pop is taking the calling routine off the stack
2nd pop is taking the prior calling routine off the stack
3c is loading the lsb of the inline word
3d is loading the msb of the inline word
now that the address has been incremented past the inline param its tossing that addy on the stack and then the addy of the calling routine
But since you've specifically called me out...
its pretty obvious this is getting to an inline parameter 2 calls backtvrfan wrote:And whilst we are on the 'training' mode, have a look at this snippet from A9L, and tell me what it does......because you really DO need to understand this kind of trick to get deeper into sorting out those damn inline params. Think carefully ..... bragging points to whoever gets this first. [no not mpaton or sailorbob....]
Code: Select all
3695: cc,38 pop R38 R38 = pop(); 3697: cc,3a pop R3a R3a = pop(); 3699: b2,3b,3c ldb R3c,[R3a++] R3c = [R3a++]; 369c: b2,3b,3d ldb R3d,[R3a++] R3d = [R3a++]; 369f: c8,3a push R3a push(R3a); 36a1: c8,38 push R38 push(R38);
the first pop is taking the calling routine off the stack
2nd pop is taking the prior calling routine off the stack
3c is loading the lsb of the inline word
3d is loading the msb of the inline word
now that the address has been incremented past the inline param its tossing that addy on the stack and then the addy of the calling routine
Re: Inline parameters(arguments)
Playing devils advocate here....
You cannot know from that snippet of code at 0x3695 alone that the "pop 3a" instruction is pulling a prior caller's return address from the stack. The calling routine itself may have pushed a value onto the stack before calling 0x3695. You need to see what is happening beforehand, hence the mpaton 0x5656 imaginary example.
You cannot know from that snippet of code at 0x3695 alone that the "pop 3a" instruction is pulling a prior caller's return address from the stack. The calling routine itself may have pushed a value onto the stack before calling 0x3695. You need to see what is happening beforehand, hence the mpaton 0x5656 imaginary example.
- cgrey8
- Administrator
- Posts: 11304
- Joined: Fri Jun 24, 2005 5:54 am
- Location: Acworth, Ga (Metro Atlanta)
- Contact:
Re: Inline parameters(arguments)
What's being popped into R38 seems more like a distraction for this example than useful information. Without more code before and after, it's difficult for me to understand why the value held in R38 was even put on the stack. This piece of code obviously knows about the presence of it, whatever it is, and is reloading the stack with the value unscathed so whatever code is to follow can pop it back off the stack and do whatever with it.
The thing I missed earlier that I'm now assuming tvrfan's point was is that the 2 bytes loaded into R3c and R3d were being pulled off a byte at a time via ldb. Pulling the word-sized data out using ldw could be unsafe since the pointer value in R3a might be odd. The code avoids caring by pulling the in-line two bytes off individually and storing them on a word-aligned boundary. With the word loaded into R3c (an even address), it can be safely operated on as a word. It would've been helpful to see an instruction using R3c as a word to clue me in that this is what was happening. Without that, it's really undefined whether those were 2 in-line data byte values or a single in-line 2-byte value.
Or have I gone off the rails again?
The thing I missed earlier that I'm now assuming tvrfan's point was is that the 2 bytes loaded into R3c and R3d were being pulled off a byte at a time via ldb. Pulling the word-sized data out using ldw could be unsafe since the pointer value in R3a might be odd. The code avoids caring by pulling the in-line two bytes off individually and storing them on a word-aligned boundary. With the word loaded into R3c (an even address), it can be safely operated on as a word. It would've been helpful to see an instruction using R3c as a word to clue me in that this is what was happening. Without that, it's really undefined whether those were 2 in-line data byte values or a single in-line 2-byte value.
Or have I gone off the rails again?
...Always Somethin'
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
-
decipha
Re: Inline parameters(arguments)
x2, just by looking at the example given alone my initial thought was that it was pushed prior to the call, figuring there was more to it, I went and looked and seen that the param was two calls backsailorbob wrote:Playing devils advocate here....
You cannot know from that snippet of code at 0x3695 alone that the "pop 3a" instruction is pulling a prior caller's return address from the stack. The calling routine itself may have pushed a value onto the stack before calling 0x3695. You need to see what is happening beforehand, hence the mpaton 0x5656 imaginary example.
Re: Inline parameters(arguments)
You haven't shown me that this is anything more than another guess. Another assumption.cgrey8 wrote:Ok, that explains more about what it is doing. The CALL pushes a return address to the stack. However because you don't want to return to data, the code using the inline data is increment the pointer pushed by the CALL past the data section. So the RET pops off the stack the correct return address. Was that the point?
Again, how did you arrive at this conclusion?
- cgrey8
- Administrator
- Posts: 11304
- Joined: Fri Jun 24, 2005 5:54 am
- Location: Acworth, Ga (Metro Atlanta)
- Contact:
Re: Inline parameters(arguments)
I don't know what you are looking for to convince you.mpaton wrote:You haven't shown me that this is anything more than another guess. Another assumption...
Any constructive feedback about my next post?
...Always Somethin'
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
Re: Inline parameters(arguments)
well, yeah, I thought I was already being quite explicit in postcgrey8 wrote:I don't know what you are looking for to convince you.mpaton wrote:You haven't shown me that this is anything more than another guess. Another assumption...
Any constructive feedback about my next post?
viewtopic.php?f=8&t=21714#p123605
Did you miss it perhaps?
- cgrey8
- Administrator
- Posts: 11304
- Joined: Fri Jun 24, 2005 5:54 am
- Location: Acworth, Ga (Metro Atlanta)
- Contact:
Re: Inline parameters(arguments)
I saw that, but didn't relate how doing all that would help with what tvrfan's point was with these 6 lines of code.
I have no clue what the stack is already loaded with.
If the values on the stack are pointers, I have no clue what they are pointing at.
And just making stuff up doesn't seem meaningful to what I suspect tvrfan's point was.
So I'm failing to understand what the exercise you described in that other post is going to help me get out of these 6 lines beyond what I've already said above.
That's not "I can't be bothered to..."
It's I have to understand what I'm supposed to get from the exercise before I'm willing to embark on it.
Now, I'm not saying there isn't any merit to going through that exercise. I'm just not seeing what the value would be without some idea of what's important, what isn't, and what to specifically pay attention to.
I have no clue what the stack is already loaded with.
If the values on the stack are pointers, I have no clue what they are pointing at.
And just making stuff up doesn't seem meaningful to what I suspect tvrfan's point was.
So I'm failing to understand what the exercise you described in that other post is going to help me get out of these 6 lines beyond what I've already said above.
That's not "I can't be bothered to..."
It's I have to understand what I'm supposed to get from the exercise before I'm willing to embark on it.
Now, I'm not saying there isn't any merit to going through that exercise. I'm just not seeing what the value would be without some idea of what's important, what isn't, and what to specifically pay attention to.
...Always Somethin'
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
Re: Inline parameters(arguments)
Oops - Thanks Bob - I thought I had said "subroutine starts here" ...agree that little piece of information is necessary to confirm that is what is going on. Apologies to all.sailorbob wrote:Playing devils advocate here....
You cannot know from that snippet of code at 0x3695 alone that the "pop 3a" instruction is pulling a prior caller's return address from the stack. The calling routine itself may have pushed a value onto the stack before calling 0x3695. You need to see what is happening beforehand, hence the mpaton 0x5656 imaginary example.
And for those of you reading and learning, believe it or not, this trick at 0x3695 is one of the SIMPLER ones !!.
Decipha has the answer - It's a subroutine which gets an inline param ON BEHALF OF another subroutine. (2 bytes, probably a word - but must confirm this in how caller subroutine uses it)
But, there's fancier tricks even in the old A9L.....
Code: Select all
GetbytesR1a: #subroutine calls go here (ie. CALL 77be)
77be: a1,1a,00,16 ldw R16,1a R16 = 1a;
Getbytes: # and some calls go here
77c2: cc,3c pop R3c R3c = pop();
77c4: b2,3d,3a ldb R3a,[R3c++] R3a = [R3c++];
77c7: cc,42 pop R42 R42 = pop();
77c9: b2,43,3b ldb R3b,[R42++] R3b = [R42++];
77cc: c6,17,3b stb R3b,[R16++] [R16++] = R3b;
77cf: e0,3a,f7 djnz R3a,77c9 R3a--;
if (R3a != 0) goto 77c9; #this is effectively what a djnz does
77d2: c8,42 push R42 push(R42);
77d4: c8,3c push R3c push(R3c);
77d6: f0 ret return;
Seriously, though - this is kind of stuff you MUST understand for accurate disassembly, and it takes some learning to be able to look at these snippets and immediately say "Ahhh...I see...." It's not easy.
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler
https://github.com/tvrfan/EEC-IV-disassembler
Re: Inline parameters(arguments)
this is all about understanding and not guessing. Even if you guess correctly, you will have no understanding. Even decip[ha's answer does not show understanding. He knows (as you may do) what this code is there for, so he chooses to say that it's obvious what is going on, and not explain HOW he knows.cgrey8 wrote:I saw that, but didn't relate how doing all that would help with what tvrfan's point was with these 6 lines of code.
I have no clue what the stack is already loaded with.
It is not obvious.
I was asking somebody, who could be you, to use the manuals and work out what was relevant on the stack, and where the stack pointed after each instruction. If you have no clue what the values on the stack are, then you would say so. Many vlues on the wrong side of the stack pointer don't point anywhere useful anyway.cgrey8 wrote:If the values on the stack are pointers, I have no clue what they are pointing at.
And that's it isn't it.cgrey8 wrote:And just making stuff up doesn't seem meaningful to what I suspect tvrfan's point was.
So I'm failing to understand what the exercise you described in that other post is going to help me get out of these 6 lines beyond what I've already said above.
That's not "I can't be bothered to..."
It's I have to understand what I'm supposed to get from the exercise before I'm willing to embark on it.
Now, I'm not saying there isn't any merit to going through that exercise. I'm just not seeing what the value would be without some idea of what's important, what isn't, and what to specifically pay attention to.
You are being asked to trust tvrfan and I that if you do the work, you will gain understanding, and you will be able to use that understanding to work out more complex examples than this, perhaps when tvrfan and I are no longer on this forum. Not trusting, is really close to "can't be bothered". jsa and ironmanisanemic seem prepared to do this work and seem to value the understanding they will get.
I don't mind if you don't want to trust, but I do ask you to stop making guesses or long explanation why you think the questions aren't useful, at least until ironmanisanemic and jsa get a chance to try.
Michael
Re: Inline parameters(arguments)
I have been staying out of mpaton/cgrey discussion so far, but I want to say I agree with mpaton in the important points -
What I am trying to do is to help people UNDERSTAND. Believe me when we say this is actually hard to do. It needs study.
Decipha did say about what the code snippet 0x3695 does at the 'mechanical' level, but not its intent/why and I missed it. I've given the answer away now (sorry to mpaton again).
To repeat - that snippet of code defines a subroutine which actually gets an inline parameter on behalf of a calling subroutine. This means in the disassembly, that subroutine itself (0x3695) has no inline parameters, but any subroutine that calls it WILL, and there's no obvious instant sign for it. THIS IS ONE OF MANY CASES. When you get to the multibanks, they do this inline parameter thing in a very different way, partly because the data may be in a different bank, but they have similar and new tricks to learn.
I've had 30 years of IT, of which about 10 was lower level stuff like this EEC code, and it took me a while (at least 20 hours) to read and understand how the 8061 uses its stack and interrupts and 'map' this to an example EEC dump. And that's me, an 'expert' (using that word just for comparison). Even if you've done lots of code like 'C' and Javascript, it doesn't give much insight into how the assembler opcode and CPU levels work.
It's that jump between this is what it does in code to this is what it does by purpose/design. That's the challenge.
We haven't really even talked about 'real time' yet. When a PIP (dizzy signal) comes in, and what happens then. That's a whole other world.
What I am trying to do is to help people UNDERSTAND. Believe me when we say this is actually hard to do. It needs study.
Decipha did say about what the code snippet 0x3695 does at the 'mechanical' level, but not its intent/why and I missed it. I've given the answer away now (sorry to mpaton again).
To repeat - that snippet of code defines a subroutine which actually gets an inline parameter on behalf of a calling subroutine. This means in the disassembly, that subroutine itself (0x3695) has no inline parameters, but any subroutine that calls it WILL, and there's no obvious instant sign for it. THIS IS ONE OF MANY CASES. When you get to the multibanks, they do this inline parameter thing in a very different way, partly because the data may be in a different bank, but they have similar and new tricks to learn.
I've had 30 years of IT, of which about 10 was lower level stuff like this EEC code, and it took me a while (at least 20 hours) to read and understand how the 8061 uses its stack and interrupts and 'map' this to an example EEC dump. And that's me, an 'expert' (using that word just for comparison). Even if you've done lots of code like 'C' and Javascript, it doesn't give much insight into how the assembler opcode and CPU levels work.
It's that jump between this is what it does in code to this is what it does by purpose/design. That's the challenge.
We haven't really even talked about 'real time' yet. When a PIP (dizzy signal) comes in, and what happens then. That's a whole other world.
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler
https://github.com/tvrfan/EEC-IV-disassembler
Re: Inline parameters(arguments)
Well the answer may be given away, but I don't see how the answer is right, yet.
To the best of my understanding this is literal application of the texts linked in another thread to the example above.
Please critique, with detailed explanation of my misunderstanding.
To the best of my understanding this is literal application of the texts linked in another thread to the example above.
Please critique, with detailed explanation of my misunderstanding.
Code: Select all
So from the posts above the example sequence starts at x5656
Sub 3695
3695: cc,38 pop R38 R38 = pop();
The processor arrives here from x5656
The stack has x5659 at the top placed by the preceding CALL
R38 means Register 38 located at address x0038 which is RAM
POP takes x5659 from the stack and stores it in R38
At this point the known stack is empty, as the example provided
gives us nothing to work from, or the stack contains nothing.
3697: cc,3a pop R3a R3a = pop();
Assuming our learned tutors know the stack is empty, hence no info.
POP stores 0x0000 at R3A being address x003A.
POP stores a WORD so it is both R3A and R3B as the WORD target.
3699: b2,3b,3c ldb R3c,[R3a++] R3c = [R3a++];
Opcode B2 is an Indirect or Indirect Auto version of LDB or LoaD Byte.
Operand 3B is odd, indicating Indirect Auto which is also described as
Long Indexed Address Mode.
The significance of Auto remains unclear to me so far.
It appears to me that the Byte from R3C is stored at R3B.
So x00 is is stored at R3B.
So now the most significant byte of the WORD at R3A & R3B is overwritten.
WHAT!!! that can't be right, but why ?
369c: b2,3b,3d ldb R3d,[R3a++] R3d = [R3a++];
Opcode and Mode as above.
This time it appears to me that the Byte from R3D is now stored at R3B.
So x00 is is stored at R3B, overwriting the value from R3C.
So now the most significant byte of the WORD at R3A & R3B is overwritten twice.
DOUBLE WHAT!!! that can't be right, but why ?
369f: c8,3a push R3a push(R3a);
The value 0x0000 (see line 3697) is placed at the top of the stack by PUSH
It is the WORD R3A & R3B, note R3B twice overwritten.
36a1: c8,38 push R38 push(R38);
The value 0x5659 (see line 3695) is placed at the top of the stack by PUSH
The value 0x0000 is now second in the stack
Our subroutine now stops because there is no RET or similar mechanism.
I imagine the watchdog timer kicks in eventually and
the processor restarts at 0x2000
.
.
.
Starting here:
0x5656 call 3695
Call places x5659 from the program counter on the stack
The address WORD is odd, contravening the EVEN requirement
Then program counter receives x3695, so the processor executes line x3695
0x5659 word $0020
0x565B word $0122
0x565D stb R38,#$0000
Cheers
John
95 Escort RS Cosworth - CARD QUIK COSY ANTI / GHAJ0
Moates QH & BE
ForDiag
John
95 Escort RS Cosworth - CARD QUIK COSY ANTI / GHAJ0
Moates QH & BE
ForDiag
Re: Inline parameters(arguments)
Unfortunately the stack does not work like that and if you keep on pulling data from the stack you end up reading data from beyond the stack origin and a stack underflow occurs.jsa wrote: 3697: cc,3a pop R3a R3a = pop();
Assuming our learned tutors know the stack is empty, hence no info.
POP stores 0x0000 at R3A being address x003A.
POP stores a WORD so it is both R3A and R3B as the WORD target.
Indirect with auto-increment is a better description and may help your understanding.jsa wrote:Indirect Auto.....The significance of Auto remains unclear to me so far.
No, see Figure 2-6. Instruction Format in AP-248.jsa wrote:It appears to me that the Byte from R3C is stored at R3B.
Understanding these items will help with the rest.
The way the example's been given doesn't help in figuring out what's going on, maybe this will.
Code: Select all
3e28: ef,29,f8 call 3654
3e2b: 08,01 dcw 0108Code: Select all
3654: 28,3f scall 3695Code: Select all
3695: cc,38 popw R38
3697: cc,3a popw R3a
3699: b2,3b,3c ldb R3c,[R3a++]
369c: b2,3b,3d ldb R3d,[R3a++]
369f: c8,3a pushw R3a
36a1: c8,38 pushw R38-
decipha
Re: Inline parameters(arguments)
very good derek thats much easier to follow
------------------------------------------------------------------------------------
call 3654 = stack [3e2b]
scall 3695 = stack [3656, 3e2b]
popw = 38 = 3656, stack [3e2b]
popw = 3a = 3e2b, stack []
ldb 3c = [3e2b], 3c = 08, 3a = 3e2c
ldb 3d = [3e2c], 3d = 01, 3a = 3e2d
pushw =3a = stack [3e2d]
pushw =38 = stack [3656,3e2d]
------------------------------------------------------------------------------------
call 3654 = stack [3e2b]
scall 3695 = stack [3656, 3e2b]
popw = 38 = 3656, stack [3e2b]
popw = 3a = 3e2b, stack []
ldb 3c = [3e2b], 3c = 08, 3a = 3e2c
ldb 3d = [3e2c], 3d = 01, 3a = 3e2d
pushw =3a = stack [3e2d]
pushw =38 = stack [3656,3e2d]
- cgrey8
- Administrator
- Posts: 11304
- Joined: Fri Jun 24, 2005 5:54 am
- Location: Acworth, Ga (Metro Atlanta)
- Contact:
Re: Inline parameters(arguments)
Agreed.decipha wrote:very good derek thats much easier to follow...
And thank you, decipha, for not confusing your explanation with "correct endianness." I actually prefer viewing the example your way.
...Always Somethin'
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
89 Ranger Supercab, 331 w/GT40p heads, ported Explorer lower, Crane Powermax 2020 cam, FMS Explorer (GT40p) headers, aftermarket T5 'Z-Spec', GUFB, Moates QuarterHorse tuned using BE&EA
Member V8-Ranger.com
Re: Inline parameters(arguments)
Thanks decipha, I'll take back my earlier comment, you Do have your head around how this works.decipha wrote:very good derek thats much easier to follow
------------------------------------------------------------------------------------
call 3654 = stack [3e2b]
scall 3695 = stack [3656, 3e2b]
popw = 38 = 3656, stack [3e2b]
popw = 3a = 3e2b, stack []
ldb 3c = [3e2b], 3c = 08, 3a = 3e2c
ldb 3d = [3e2c], 3d = 01, 3a = 3e2d
pushw =3a = stack [3e2d]
pushw =38 = stack [3656,3e2d]
Now, I hope we can go back to my earlier simpler example from HHX0, specifically
This is simpler than the previous example, as there is only one pop instruction in those 3 instructions.mpaton wrote:So now ironman has "fixed" all the calls to the 1D lookups, what are they doing?
Here's the first call
3F3B EF6006 call L459E
3F3E 8E00 word $008E
3F40 B600 word $00B6
or maybe we have
3F3B EF6006 call L459E
3F3E 8E byte $8E
3F3F 00 byte $00
3F40 B6 byte $B6
3F41 00 byte $00
depending on whether we used word or byte for the directives. That didn't matter when we did it, because our goal was just to disassemble code as code. Now we're going to look at the data.
So what's the code at $459E look like? We know it's going to look up a 1D table (single input, single output),we know there will be interpolation code. So there are 2 inputs to this routine, and one output. The inputs are the input to the table, or more likely the address of the input, and also the table, or more likely the address of the table.
So the code at $459E is
So we see that after 45A9, it's going to execute the instructions atCode: Select all
459E 91209D L459E orb REG_9D,#$20 45A1 2006 sjmp L45A9 45A3 91209D orb REG_9D,#$20 45A6 91109D orb REG_9D,#$10 45A9 CC36 L45A9 popw REG_36 45AB B23732 ldb REG_32,[REG_36]+ 45AE B23733 ldb REG_33,[REG_36]+ 45B1 AC3334 ldzbw REG_34,REG_33 45B4 710F33 an2b REG_33,#$0F 45B7 080434 shrw REG_34,#$04 45BA 6735F00032 ad2w REG_32,$00F0[REG_34] 45BF B23734 ldb REG_34,[REG_36]+ 45C2 B23735 ldb REG_35,[REG_36]+ 45C5 C836 pushw REG_36 45C7 B23434 ldb REG_34,[REG_34] 45CA 9B320234 L45CA cmpb REG_34,$02[REG_32] 45CE 3D9D04 jb REG_9D,BIT_05,L45D5 45D1 DB0A jc L45DD 45D3 2002 sjmp L45D7 45D5 D606 L45D5 jge L45DD 45D7 65020032 L45D7 ad2w REG_32,#$0002 45DB 27ED sjmp L45CA 45DD 71DF9D L45DD an2b REG_9D,#$DF 45E0 B23336 ldb REG_36,[REG_32]+ 45E3 B23338 ldb REG_38,[REG_32]+ 45E6 7A3236 sb2b REG_36,[REG_32] 45E9 7A3334 sb2b REG_34,[REG_32]+ 45EC 7A3238 sb2b REG_38,[REG_32] 45EF 3C9D04 jb REG_9D,BIT_04,L45F6 45F2 DB09 jc L45FD 45F4 2002 sjmp L45F8 45F6 D605 L45F6 jge L45FD 45F8 91209D L45F8 orb REG_9D,#$20 45FB 1338 negb REG_38 45FD 7C3438 L45FD ml2b REG_38,REG_34 4600 9C3638 divb REG_38,REG_36 4603 359D02 jnb REG_9D,BIT_05,L4608 4606 1338 negb REG_38 4608 763238 L4608 ad2b REG_38,[REG_32] 460B 1139 clrb REG_39 460D 71DF9D an2b REG_9D,#$DF 4610 71EF9D an2b REG_9D,#$EF 4613 F0 ret
45A9
45AB
45AE
Ironman, or jsa, would you like to explain what those 3 instructions do? you'll need to have downloaded the 8061 instruction guide.
Michael
Once we have those decoded, it will get interesting, as we'll discover one of the Ford coding conventions.
Michael
Re: Inline parameters(arguments)
TO jsa, from above post.
That's good, but misses a few vital things. A couple of pointers -
At the end you talk about a RET not being there.
OK - please understand this was just a snippet inside the subroutine. It does do a RET later. Also assume that somewhere there is a CALL 3695 instruction to get here.
Which leads on to -
You implied that the stack would be empty. That's not true. Go and check what happens when a CALL/SCALL opcode is executed.
Processor starts at 0x2000 as part of it's initialisation process, when you power it on, or do a reset.
Autoincrement - a lot of CPUS have this feature, basically because it's a time saver, as it already has the target register in its processing unit, it's quicker to increment it whilst it's
there, before writing it back to RAM. Autoincrement adds 1 if it's a byte instruction or 2 if it's a WORD instruction.
So in the code snippet the value of R3a does change.
If anyone needs some more explanation of the symbols (e.g. the square brackets) just ask, and I will do that.
That's good, but misses a few vital things. A couple of pointers -
At the end you talk about a RET not being there.
OK - please understand this was just a snippet inside the subroutine. It does do a RET later. Also assume that somewhere there is a CALL 3695 instruction to get here.
Which leads on to -
You implied that the stack would be empty. That's not true. Go and check what happens when a CALL/SCALL opcode is executed.
Processor starts at 0x2000 as part of it's initialisation process, when you power it on, or do a reset.
Autoincrement - a lot of CPUS have this feature, basically because it's a time saver, as it already has the target register in its processing unit, it's quicker to increment it whilst it's
there, before writing it back to RAM. Autoincrement adds 1 if it's a byte instruction or 2 if it's a WORD instruction.
So in the code snippet the value of R3a does change.
If anyone needs some more explanation of the symbols (e.g. the square brackets) just ask, and I will do that.
TVR, kit cars, classic cars. Ex IT geek, development and databases.
https://github.com/tvrfan/EEC-IV-disassembler
https://github.com/tvrfan/EEC-IV-disassembler
Who is online
Users browsing this forum: No registered users and 37 guests