hugsy / cemu

Cheap EMUlator: lightweight multi-architecture assembly playground
MIT License
946 stars 101 forks source link

Aarch64: CBZ causes emulator exception #53

Closed zcodegit closed 2 years ago

zcodegit commented 4 years ago

Hello,

I am testing a very small program for Aarch64 which is disassembled correctly in CEMU, as I've checked with two different disassemblers:

movz x0, #0 movz x1, #0x20 movz x2, #0x3a movz x3, #0xa cmp x2, x3 cset x3, lt cbz x3, #0x4024 movz x4, #0xc8 adds x4, x2, x4 ret

Note that CBZ instruction has an offset of 0x4024, which is correct. I've left the text section at 0x4000, which is the default.

When running through the emulator, the DBZ causes an exception:

2020/09/13 - 23:09:52: Executing - 0x4018: cbz x3, #0x8024 2020/09/13 - 23:09:52: [logger] Error - An error occured: Fetch from non-executable memory (UC_ERR_FETCH_PROT) 2020/09/13 - 23:09:52: Exception - pc=0x8024 , sp=0x6000: Fetch from non-executable memory (UC_ERR_FETCH_PROT) 2020/09/13 - 23:09:52: Runtime - Ending emulation context

This is because it is trying to jump to 0x8024. While the issue may be in the emulator itself, it may just be a faulty configuration in CEMU where the emulator is not set to start at 0x4000. Typically Aarch64 loads the first instruction at 0x8000, so that might be the default setting of the emulator.

zumpchke commented 3 years ago

@zcodegit CBZ instruction offset is PC relative. So it should be at #0x24

CBZ Compare and Branch on Zero compares the value in a register with zero, and conditionally branches to a label at a PC- relative offset if the comparison is equal. It provides a hint that this is not a subroutine call or return. This instruction does not affect condition flags.

hugsy commented 2 years ago

Cleanup