S12Z CPU assembly does not match with manual

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S12Z CPU assembly does not match with manual

Jump to solution
1,942 Views
kloetpatra
Contributor I

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?

Labels (1)
Tags (3)
0 Kudos
1 Solution
1,210 Views
MJW
NXP Employee
NXP Employee

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

View solution in original post

0 Kudos
8 Replies
1,211 Views
MJW
NXP Employee
NXP Employee

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

0 Kudos
1,210 Views
kloetpatra
Contributor I

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...

0 Kudos
1,210 Views
MJW
NXP Employee
NXP Employee

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?

0 Kudos
1,210 Views
kloetpatra
Contributor I

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

0 Kudos
1,210 Views
MJW
NXP Employee
NXP Employee

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).

0 Kudos
1,210 Views
kloetpatra
Contributor I

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:

  • Win XP 32-Bit SP 3 - Intel Core 2 Duo E6600
  • Win 7 64-Bit SP 1 - Intel i5-4670K


0 Kudos
1,210 Views
MJW
NXP Employee
NXP Employee

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

0 Kudos
1,210 Views
eelcodeutekom
Contributor I

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.

0 Kudos