The following C code
#define SUCCESS 0
#define UART_SUCCESS 0
#define UART_BUFFER_FULL -3
...
return result == SUCCESS ? UART_SUCCESS : UART_BUFFER_FULL;
produces this asm:
mov a,r7
cjne a,#0x01,00122$
00122$:
clr a
rlc a
mov r7,a
jz 00109$
mov r7,#0x00
sjmp 00110$
00109$:
mov r7,#0xFB
00110$:
mov dpl,r7
C$uart_0.c$205$1$39 ==.
XG$uart_writec$0$0 ==.
ret
for SDCC V3.20, x51, --model-large, --nooverlay
When assembled, it causes the MCU to reset at the instruction cjne a,#0x01,0.
The correct, unoptimized assembly should be:
mov a,r7
cjne a,#0x00,00109$
mov r7,#0x00
sjmp 00110$
00109$:
mov r7,#0xFB
00110$:
mov dpl,r7
C$uart_0.c$205$1$39 ==.
XG$uart_writec$0$0 ==.
ret
The corresponding if else structure
if (result == SUCCESS) {
return UART_SUCCESS;
} else {
return UART_BUFFER_FULL;
}
realizes the same problem in the asm.
The MCU should not reset at that instruction as it is perfectly valid. Do not mistake the relative offet 0 for a jump to address 0x0000.
Furthermore the generated code may be less optimal but it is not wrong. The CJNE will subtract 0x01 and only when A is zero will it set the Carry Flag which is subsequently shifted into A.