From 158a2a79f1df89493c27a6191c2513ec0418641f Mon Sep 17 00:00:00 2001 From: stefanrueger Date: Sun, 9 Nov 2025 20:15:23 +0100 Subject: [PATCH] No longer use register names in I/O space for ldi operands When disassembling AVRDUDE uses known labels for ldi operations that initialise a register pair, eg, ldi r30, lo8(nvm.ctrla) ; 0xcb = 203 ldi r31, hi8(nvm.ctrla) ; 0x01 = 1 out cpu.ccp, r24 st Z, r18 This is meant to illustrate a possible intention of the code. It is not unusual to see a base register loaded, for example the USARTC0 register base, into the Y or Z register pair and read write with displacement from specific USARTC0 register bytes using the ldd and std opcodes. However, sometimes these labels are misleading when, eg, the register pair is just initialised as a counter. In particular that can easily happen for I/O register addresses for which there are fewer use cases to put them into a register pair as the in/out opcodes are short and no savings would be made using ldd/std. For example, ldi r28, lo8(gpio.gpior9) ; 0x09 = 9 ldi r29, hi8(gpio.gpior9) ; 0x00 = 0 is most likely used as a 16-bit counter initialised with 9. This would better be disassembled as ldi r28, 0x09 ; 9 ldi r29, 0x00 ; 0 This commit does so by removing the use of registers in I/O space as symbolic ldi operands when loading a register pair. --- src/disasm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/disasm.c b/src/disasm.c index 8bbe71cb..144fda71 100644 --- a/src/disasm.c +++ b/src/disasm.c @@ -922,8 +922,11 @@ static const char *get_ldi_name(int op1, int op2, Op_context *oxp) { if((s = find_symbol(*c, addr*awidth))) break; if(s && s->name) { // Label matches the address loaded into register pair - s->used = 1; - return str_ccprintf("%s%s(%s)", awidth == 2? "pm_": "", ra & 1? "hi8": "lo8", s->name); + // Don't use register names in I/O space as ldi label names + if(s->type != 'M' || (uint16_t) addr >= 64 + cx->dis_io_offset) { + s->used = 1; + return str_ccprintf("%s%s(%s)", awidth == 2? "pm_": "", ra & 1? "hi8": "lo8", s->name); + } } if((ra | 1) == 31 && oxp->is_lpm && addr >= cx->dis_start && addr < cx->dis_end) { if(cx->dis_pass == 1)