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

Reply via email to