Hi,
I got the following ASM Instruction: "ST.b D0,$1218" (.b can be omitted here)
Looking at the manual this Instruction would encode to "C0 12 18".
But looking at the assembly output generated by as12lisa.exe I get "C4 12 18"
The proper reason I ask for, is because I am not able to store values in memory through D0. Maybe there is a connection.
It works when I do:
TFR D0,D6
ST.b D6,$1218
Why it's not possible to store directly from D0?
Solved! Go to Solution.
Hello,
actually "ST D0,$1218" correctly encodes to "C4 12 18" (see Table-A2 in the S12Z CPU RM, for example).
According to the RM, "C0 12 18" means "ST D2,$1218".
Also, "ST" doesn't use any size specifiers; the transfer size is defined by the source register size.
That means the sequence
TFR D0,D6
ST D6,$1218
zero-extends the content of D0 into D6 before the 32-bit data in D6 is stored into 4-bytes of memory starting at address $001218.
The content of D0 ends up stored at address $00121B.
Hope that helps.
Best Regards,
MJW
Hello,
actually "ST D0,$1218" correctly encodes to "C4 12 18" (see Table-A2 in the S12Z CPU RM, for example).
According to the RM, "C0 12 18" means "ST D2,$1218".
Also, "ST" doesn't use any size specifiers; the transfer size is defined by the source register size.
That means the sequence
TFR D0,D6
ST D6,$1218
zero-extends the content of D0 into D6 before the 32-bit data in D6 is stored into 4-bytes of memory starting at address $001218.
The content of D0 ends up stored at address $00121B.
Hope that helps.
Best Regards,
MJW
Thank you, for pointing that out. I thought the register number is encoded in BCD format. Also the "not working" ST D0,$1218 instruction was actually working. I had a bug in my memory read function which only read 24 bit and worked due to alignment when storing from a 32-Bit register.
An additional problem came up, maybe you have a explanation or hint for that too:
At branches with negative offsets (where the target location address is lower than the actual Instruction address) the PC seems to be loaded with an invalid location due to wrong calculation of offset.
When I modify the program so that JMP instructions are used (absolute jump addresses) instead of a negative branch everything works as expected.
As far as I can see the assembler does always use the branch Instructions with REL_SIZE bit set when using labels. Even at branches with offsets in range to PC-64. This should not be a problem to me in general, but i don't know why the twos complement offset is not calculated correctly.
This is a listing of my sample program.
Abs. Rel. Loc Obj. code Source line
---- ---- ------ --------- -----------
63 63 ORG RAM_MAIN
64 64 startup:
65 65 a001220 1B03 0011 LD S,#RAM_STACK
001224 FF
66 66 a001225 0F00 0000 MOV.l #0,retError
001229 0012 10
67 67 a00122C 9411 LD D0,#$11
68 68 a00122E BA00 1243 JMP test
69 69
70 70 branch:
71 71 a001232 9155 66 LD D3,#$5566
72 72 a001235 9677 8899 LD D6,#$778899AA
001239 AA
73 73 a00123A 97BB CCDD LD D7,#$BBCCDDEE
00123E EE
74 74 a00123F BA00 124B JMP done
75 75
76 76 test:
77 77 a001243 9522 LD D1,#$22
78 78 a001245 2092 32 BRA branch
79 79 a001248 9033 44 LD D2,#$3344
80 80
81 81 done:
82 82 a00124B 00 BGND
With my debugger I read the following register values when program stops execution:
D0: 11
D1: 22
D2: 0000
D3: 0000
D4: 0000
D5: 0000
D6: 00000000
D7: 00000000
X: 000000
Y: 000000
SP: 0011FF
PC: 002478
In line 78 you can see that PC will increase by 0x1232 -> PC = 0x1232 + 0x1245 = 0x2477
0x2477 Is not a valid memory location so PC is incremented by one and CPU Halts
If I change the the binary with "20 FF ED" instead of "20 92 32" which is the correct twos complement instruction for "BRA -19" the program works expected and the register values are correct.
Also if I use the "BRA -19" it'll be encoded to the correct twos complement and even the short form with REL_SIZE bit cleared.
Is there something i'm doing wrong, or is that a bug?
Edit: I noticed that it's the actual address of the marker if it's at a lower address. In case of a positive offset the assembler correctly uses the offset, and not the address of the marker. So it seems like a real bug...
I just tried this code in CW 10.6 (+latest updates):
8171: | LD | S, #__SEG_END_SSTACK ; initialize the stack pointer |
main:
00FE0000 1B03001100 | LD | S,#4352 |
8173: | LD | D0,#$11 |
00FE0005 9411 | LD | D0,#17 |
8174: | JMP | test |
00FE0007 BAFE001C | JMP | 16646172 |
8177: | LD | D3,#$5566 |
branch:
00FE000B 915566 | LD | D3,#21862 |
8178: | LD | D6,#$778899AA |
00FE000E 96778899AA | LD | D6,#2005440938 |
8179: | LD | D7,#$BBCCDDEE |
00FE0013 97BBCCDDEE | LD | D7,#-1144201746 |
8180: | JMP | done |
00FE0018 BAFE0024 | JMP | 16646180 |
8182: | LD | D1,#$22 |
test:
00FE001C 9522 | LD | D1,#34 | |
8183: | BRA | branch | |
00FE001E 20FFED | BRA | *-19 | ;abs = 0xFE000B |
8184: | LD | D2,#$3344 | |
00FE0021 903344 | LD | D2,#13124 | |
8186: | BGND |
done:
00FE0024 00 | BGND |
This does look fine to me, even if the offset is still in long format for the BRA instruction.
What tool(-version) are you using to assemble your code?
I am using as12lisa.exe from the latest Special Edition: CodeWarrior for Microcontrollers 10.6 (Eclipse, Offline)
The version of the assembler is
Assembler for HCS12Z V-5.0.014 Build 14037, Feb 7 2014
Build 14037
To assemble my code the call looks like:
C:\Freescale\CW MCU v10.6\MCU\S12lisa_Tools\Build_Tools\as12lisa.exe -FA2 -L=test.lst test.asm
Mine says:
Assembler for HCS12Z V-5.0.014 Build 14141, May 22 2014
I recommend updating to the latest version (in the CW 10.6 GUI, select Help->Check for Updates).
Updated to Assembler for HCS12Z V-5.0.014 Build 14141, May 22 2014
Problem still exists. There is no difference in using it via GUI, Command Line, or via Code Warrior with a ASM source file in project.
Tried it on two different Systems:
Yes, I was able to reproduce this (sorry for the delayed response).
The issue seems to be related to the usage of the "ORG" assembly directive.
If this is removed, and a regular "SECTION" is defined instead, the branch instruction is assembled correctly.
This would also be a valid workaround for the problem, but requires invoking the linker (and a linker script) to
generate the final ELF (and s-record) files.
Best Regards,
MJW
Hello MJW,
Thank you very much for your explanation. But.................
Heinz tried alternative instructions because, he noticed that he could not store the contents of D0 to memory using "ST D0,$1218".
So despite your efforts, the question still stands. Can the contents of D0 be stored to memory using "ST D0,$1218" ?
Best Regards,
Eelco.