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 |
|
|
|