I'm working with a freescale FRDM-MKL25Z4 development board, writing some minimal code. I find that the simulator and the development board seem to disagree on the behavior. also in my disassembly window I often get different disassembly for the same instruction.
memcpy: 0x00000292 B5B0 DCW 0xB5B0 << why isn't this a PUSH? 0x00000294 B089 DCW 0xB089 0x00000296 4613 DCW 0x4613 ... 0x000002DC BDB0 DCW 0xBDB0
memset: 0x000002DE B5B0 PUSH {r4-r5,r7,lr} <<why is it PUSH here? 0x000002E0 B088 SUB sp,sp,#0x20
any help would be appreciated.
0x00000292 B5B0 DCW 0xB5B0 << why isn't this a PUSH?
Because something tricked the tools into believing this is not code. It's being displayed as data.
How do the tools decide this?
I have seen lots of debuggers that shows correct assembly from the current position and forward, but might show bytes as data for earlier addresses. I have also seen a number of debuggers who shows incorrect processor instructions for earlier addresses because the debugger has tried to step back byte-for-byte while trying to identify what might be an instruction.
A label doesn't automagically tell that an address is a jump target so must be the first byte/word of a processor instruction. With debug information, it should be reasonably simple to know what is code. With just a map file, it isn't so easy.
A commercial grade disassembler spends a number of passes walking over the bytes just to pick up all the hints what is code and what is data.
Did your project contain full debug information?
No, Not at the moment. It was built with clang llvm. the debug information doesn't seem to work with uvision. But really I just want the uvision simulator to execute the code. It doesn't seem to interpret the DCW instructions for some reason.
DCW is irrelevant - the presentation doesn't interfere with the simulators ability to run code.
A processor do not care if the assembler file thinks a byte is part of data or part of code. When a jump goes to a specific address, the processor will try to decode the data at that address as code.
So if your code jumps to memcpy(), then the simulator will perform as it should. And in that case, it should also disassemble that block of data as code since it understands from the PC that it is expected to be code.
This is the code at the reset vector:
LR:0xFFFF_FFFF R7:0x0000_0000
0x000001E8 B580 DCW 0xB580 << Should set lr to the value in r7
pc gets incremented that is all.
however if it is ran here:
0x000002E0 B580 PUSH {r7,lr} << well I get a hard reset but its diffrent results for the same input.
I upload my elf to here. It blinkys my frdm-kl25z three very bright colors.
drive.google.com/.../view
Your stack alignment is screwed up, you can't use 0x20002FFF, it needs to be 0x20003000, it will decrement from there. A lot of linker scripts have this kind of broken definition.
Thanks that's very useful! I made the change.