I agree, parts of that assembly are weird. I don't think that code would
work properly.
push a
ld (0x01, sp), a
So, take the argument in A register, push it onto the stack ('cause we
want to later use A to pass a value of zero in call to _tm1638_curs)...
but then load the same value from A into the stack, overwriting what we
just pushed?! Okay, not the end of the world, just a redundant operation.
ld a, (0x01, sp)
add a, #0x30
pop a
jp _tm1638_putc
Take the original function argument value previously put on the stack
and load into A reg, add ASCII '0' to it... then overwrite that
resultant value in A by popping the stack value?! Yes, that will pass
the wrong value to _tm1638_putc. Definitely something bad here.
I can verify this behaviour. I compiled the following and got identical
assembly for the test_number function.
void disp_clear(void) {
}
void disp_curs(char p) {
(void)p;
}
void disp_putc(char c) {
(void)c;
}
void test_number(char tnum) {
disp_clear();
disp_curs(0);
disp_putc(tnum + '0');
}
void main(void) {
test_number(9);
while(1);
}
In fact, it's wrong even when compiled with --no-peep:
_test_number:
push a
ld (0x01, sp), a
; foo.c: 15: disp_clear();
call _disp_clear
; foo.c: 16: disp_curs(0);
clr a
call _disp_curs
; foo.c: 17: disp_putc(tnum + '0');
ld a, (0x01, sp)
add a, #0x30
pop a
jp _disp_putc
00101$:
; foo.c: 18: }
pop a
ret
My SDCC version:
SDCC :
mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502
4.2.0 #13081 (MINGW64)
Regards,
Basil Hussain
_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user