achan1989 / ghidra-65816

WDC 65816 processor module for Ghidra
MIT License
22 stars 3 forks source link

Even with MF: 1 and XF: 1, LDX takes 3 bytes instead of 2. #4

Closed s5bug closed 5 years ago

s5bug commented 5 years ago

I have a2 03 9e 40 21 and need to get

LDX #$0x03
STZ $0x2140,X

and not

LDX #$0x9e03
RTI

image

achan1989 commented 5 years ago

I think I fixed this bug in v1.0.1 of the plugin -- when I try to disassemble that sequence myself it seems to work like you want. Can you check that you're using the latest version and let me know if you still have the problem? You'll have to restart Ghidra, and probably clear and re-disassemble those bytes.

s5bug commented 5 years ago

I git cloned this repository to my plugins directory about 20 minutes ago, so outdated version shouldn't be a problem.

achan1989 commented 5 years ago

Damn. The script manager has a "sleigh" group, with a "DebugSleighInstructionParse" script. Can you put the cursor on the first byte of the LDX instruction, run the script, and paste the output here?

s5bug commented 5 years ago
Successfully compiled: DebugSleighInstructionParse.java
DebugSleighInstructionParse.java> Running...
DebugSleighInstructionParse.java> 
NOTE: bitrange's number leftmost/most-significant bit as 0 (zero).
      This bit numbering agrees with the context field specification
      but differs from token field specification.  The bit correspondence
      for token fields depends upon the specific token size/endianess and
      current byte-offset of pattern matcher.

initial context bits: 10000000.00000000.00000000.00000000
resolving constructor for instruction bytes at: bus:008125
decide on instruction bits: byte-offset=0, bitrange=(0,7), value=0xa2, bytes=(10100010)
   decendent constructors for decision node (complete tree dump ordered by line number):
   : {line# 854} LDX <LDX_OP>
   : {line# 863} LDX <LDX_OP>
decide on context bits: bitrange=(1,1), value=0x0, context=1(0)000000.00000000.00000000.00000000
   decendent constructors for decision node (complete tree dump ordered by line number):
   : {line# 863} LDX <LDX_OP>
check pattern[1 of 1]: {line# 863} LDX <LDX_OP>
   (  byte pattern: mask=11111111.00000000.00000000.00000000
              bytes[0-3]=10100010.00000011.10011110.01000000
             match-value=10100010.00000000.00000000.00000000 Matched
   ) -and- (
      context pattern: mask=01000000.00000000.00000000.00000000
             context(0..31)=10000000.00000000.00000000.00000000
                match-value=00000000.00000000.00000000.00000000 Matched
                  ctx_XF(1,1) == 0x0 Match
   ) Matched
LDX_OP: resolving...
   decide on instruction bits: byte-offset=0, bitrange=(5,5), value=0x0, bytes=10100(0)10
      decendent constructors for decision node (complete tree dump ordered by line number):
       LDX_OP: {line# 851} <RefImmXF>
   check pattern[1 of 1] LDX_OP: {line# 851} <RefImmXF>
      byte pattern: mask=00011100.00000000.00000000.00000000
              bytes[0-3]=10100010.00000011.10011110.01000000
             match-value=00000000.00000000.00000000.00000000 Matched
      RefImmXF: resolving...
         decide on context bits: bitrange=(1,1), value=0x0, context=1(0)000000.00000000.00000000.00000000
            decendent constructors for decision node (complete tree dump ordered by line number):
             RefImmXF: {line# 574} <RefImm16>
         check pattern[1 of 1] RefImmXF: {line# 574} <RefImm16>
            context pattern: mask=01000000.00000000.00000000.00000000
                   context(0..31)=10000000.00000000.00000000.00000000
                      match-value=00000000.00000000.00000000.00000000 Matched
                        ctx_XF(1,1) == 0x0 Match
            RefImm16: resolving...
               check pattern[1 of 1] RefImm16: {line# 558} #$<imm16>
                  byte pattern: always-Matched
                  imm16: TokenField = 0x9e03

Prototype parse successful: LDX #$0x9e03
Instruction length = 3 bytes
Instr Mask:  11111111.00000000.00000000
Instr Value: 10100010.00000000.00000000
Op-0 Mask:   00000000.11111111.11111111
Op-0 Value:  00000000.00000011.10011110
DebugSleighInstructionParse.java> Finished!

It doesn't want to parse only 2 bytes

achan1989 commented 5 years ago

Oh. Ghidra is supplying the X flag as 0, instead of the 1 that you want. This has happened to me too, and I haven't worked out exactly why it happens yet.

I bet if you opened the Register Manager and looked at the entries for ctx_XF, it wouldn't be set correctly for the address range that you want. You can double-click an entry and try to change the range, but sometimes I've seen that fail with a small "update register range failed" error in the status bar. I think I ended up having to clear bytes that were part of the range in question before Ghidra would let me set ctx_XF properly. Maybe that would work for you?

s5bug commented 5 years ago

I had to select both bytes and then manually set the register value there. Hopefully nothing else is broken in the disassembly. I'll have to write a program later to check :P

achan1989 commented 5 years ago

Cool, that's good to know. Like I said in the readme, this kind of issue is possibly one of Ghidra and/or this plugin's pain points. If you find that it keeps happening then please let me know.