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