захотелось мне немного усовершенствовать стандартный printf_tiny(), который использует внешнюю (extern) функцию putchar() для работы с uart. А именно -- вместо того, чтобы объявлять ее как extern void putchar(char), сделать extern void (*putchar)(char). В основной программе, соответственно, объявить явно этот указатель и присваивать ему по ходу дела, что захочется (ну, например, одну реализацию для синхронного, другую -- для асинхронного ввода-вывода).
Так вот, проблема в том, что sdcc генерит неправильный код. Исходный код
CODE
char putchar(char);
char (*f)(char);
int main(){
char c;
f = putchar;
c = f(9);
return 0;
}
char putchar(char c){
return c;
}
превратился после компиляции в
CODE
_main:
; тут стандартная преамбула
; a.c:26: f = putchar;
mov _f,#_putchar
mov (_f + 1),#(_putchar >> 8)
; a.c:27: c = f(9);
mov a,#00103$
push acc
mov a,#(00103$ >> 8)
push acc
push _f
push (_f + 1)
mov dpl,#0x09
ret
00103$:
; a.c:28: return 0;
mov dptr,#0x0000
ret
; a.c:31: char putchar(char c){
; -----------------------------------------
; function putchar
; -----------------------------------------
_putchar:
; a.c:32: return c;
ret
Видно, что не получилось никакого кода, который бы вызывал putchar(). Вопрос -- а как делать правильно? или SDCC просто не поддерживает такой способ вызова функций.