ASM Example Program and C Equivalent

Comparison between Assembly Code and C Code

Multi-byte math in C is a breeze compared to ASM:

C: x32 = x32 + 1234;
ASM: movlw 0xd2
addwf x32,f
movlw 04
btfsc 03.0
movlw 05
addwf x32+1,f
movlw 00
btfsc 03.0
movlw 01
addwf x32+2,f
movlw 00
btfsc 03.0
movlw 01
addwf x32+3,f

C data structures can be much more easily expressed in C for example:

C: device_list[3].flags.active_flag = 1;
ASM: bsf device_list+DL_ENTRY_SIZE*3+DL_FLAG_OFFSET, ACTIVE_FLAG

In assembly bank switching (RAM banks) and program memory paging must always be considered:

C: MyVar = 12;
ASM: movlw 0x0C
bcf status,bs7 ; Set to RAM bank 2
bsf status,bs8
movwf MyVar

Here is an example ASM function and the C equivalent:

C: void parse_userid(char var_2) {
char loop_count;
char send_reg;

for(loop_count=6;loop_count>0;loop_count--) {
send_reg=BufferRead();
shift_right(&send_reg,1,0);
if(send_reg!=' ')
do_serial_send(send_reg);
offset++;
}
UID_buffer=BufferRead();
shift_right(&UID_buffer,1,0);
UID_buffer&=0x0F;
if(UID_buffer!=0) {
do_serial_send('0');
if(UID_buffer>=10) {
UID_buffer-=10;
do_serial_send('1');
}
do_serial_send(UID_buffer+0x30);
}
if((offset^var_2)==0)
do_serial_send('*');
}
ASM:
parse_userid:
movlw 0x06
movwf loop_count ;6 loops
parse_userid_loop:
call BufferRead ;get byte from RAM
movwf send_reg ;byte to send_reg
bcf status,carry
rrf send_reg,F ;right shift to normal
movfw send_reg
xorlw ' ' ;space ?
btfss status,zero ;yes, skip next
call do_serial_send ;no, send byte
incf offset,F ;inc offset
decfsz loop_count,F ;loop count - 1
goto parse_userid_loop
;
call BufferRead ;get stored UID byte
movwf UID_buffer
rrf UID_buffer,F ;right shift byte
movlw 0x0f
andwf UID_buffer,F ;mask hi nibble
btfsc status,zero ;yes, skip next
goto UID_is_zero ;UID = 0
movlw '-' ;add dash
movwf send_reg
call do_serial_send ;send -
movlw d'10' ;10
subwf UID_buffer,W ;test magnitude
btfss status,carry ;yes, skip next
goto send_the_ones ;UID < 10
movwf UID_buffer ;UID buffer => 10
movlw "1" ;ascii 1 for tens
movwf send_reg ;W to send_reg
call do_serial_send ;send 10
send_the_ones:
movfw UID_buffer ;UID to W
addlw 0x30 ;ascii convert
movwf send_reg
call do_serial_send
UID_is_zero: ;do asteric routine
movfw var_2
xorwf offset,W ;check for loc match to
bnz $+4 ;sending digi
movlw "*"
movwf send_reg
call do_serial_send ;send * to denote
return