adriancable / 8086tiny

Official repository for 8086tiny: a tiny PC emulator/virtual machine

Home Page:www.megalith.co.uk/8086tiny

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

LEA bug

TheFox opened this issue · comments

I think your LEA implementation is wrong.

When I want to execute, for example, lea sp, ... the c variable op_from_addr is 0xf0008 which points inside mem to ES instead to SP. This is because you calculate

op_from_addr = REGS_BASE + i_reg * 2;

for your LEA implementation instead of just

op_from_addr = REGS_BASE + i_reg;

(without * 2).

Hi TheFox - I think the implementation is correct (but please let me know if you still think otherwise).

0xF0008 points inside mem to SP, not ES (which is at 0xF0010). mem is an array of unsigned char, but the registers are 16 bits. So, to convert the 16-bit register index i_reg extracted from the opcode to an index within mem, the calculation REGS_BASE + i_reg * 2 is correct.

-Adrian

Thank you for your very fast answer.

But why do I get the same address as ES, calculating REGS_BASE + REG_ES is also 0xF0008.

Edit: when I want to execute lea sp, ..., the i_reg variable is already 4. So REGS_BASE + i_reg * 2 = 0xF0000 + 4 * 2 = 0xF0008 = REGS_BASE + REG_ES.

TheFox - what do you mean when you say "why do I get the same address as ES"?

The decoder for LEA calls DECODE_RM_REG, which calls GET_REG_ADDR, which always does the calculation REGS_BASE + 2 * reg_id. So it is never REGS_BASE + REG_ES - the index into mem is always REGS_BASE + 2 * REG_ES.

Ah I see. So my REGS_BASE + REG_ES assumption is wrong. It is acctually regs16[REG_ES] or REGS_BASE + 2 * i_reg.

I think so. Also, from a heuristic point of view, if the LEA implementation was so wrong, many common programs would break, which we don't see.

-Adrian