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