Author Topic: C code and Assembly  (Read 9601 times)

0 Members and 1 Guest are viewing this topic.

Offline marsalTopic starter

  • Newbie
  • Posts: 8
C code and Assembly
« on: April 27, 2014, 06:11:09 am »
what is the best way to combine assembly code into a c source code?
also can you give me a simple c code to create a tone generator

i have attached a screen shots of the errors i am getting when i try to combine c and asm


please help me!!

my config bits are:

#include <xc.h>

/** C O N F I G U R A T I O N   B I T S ******************************/

#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF                       // CONFIG1H
#pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 30                        // CONFIG2L
#pragma config WDTEN = OFF, WDTPS = 32768                                    // CONFIG2H
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC       // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF                                                      // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF                   // CONFIG5L
#pragma config CPB = OFF, CPD = OFF                                         // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF                // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                            // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF           // CONFIG7L
#pragma config EBTRB = OFF                                                  // CONFIG7H
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: C code and Assembly
« Reply #1 on: April 27, 2014, 06:28:28 am »
On XC8 it seems you can't do the asm directive

like on X86 Visual C:

Code: [Select]
   unsigned char in_val = 255;
   char digits[3];
   digits[0] = digits[1] = digits [2] = '0';

  _asm {
     mov bl,in_val
   
loop_100:
     cmp bl,100
     jb  exit_loop_100
     inc digits[2]
     sub bl,100
     jmp loop_100
exit_loop_100:

loop_10:
     cmp bl,10
     jb  exit_loop_10
     inc digits[1]
     sub bl,10
     jmp loop_10
exit_loop_10:

     add digits[0],bl
  }

The most I've been able to achieve is this but I have to use the registers directly no moving things back from C variables to assembly registers and viceversa, but there has to be a way and I only tried for a couple of hours one day.

Code: [Select]
        asm("MOVLW 0xFF");
        asm("MOVWF 0x74");
        asm("MOVF 0x74, W");
        asm("MOVWF 0x78"); // in_val
       
        asm("MOVLW 0x30");
        asm("MOVWF 0x77");
        asm("MOVWF 0x76");
        asm("MOVWF 0x74");
        asm("MOVF 0x74, W");
        asm("MOVWF 0x75"); // digits
asm("Loop1:");
        asm("MOVLW 0x64");
        asm("SUBWF 0x78, W"); //in_val
        asm("BTFSS STATUS, 0x0");
        asm("GOTO Skip1");
       
//        asm("MOVLW 0x1");
//        asm("MOVWF 0x74");
//        asm("MOVF 0x74, W");
//        asm("ADDWF 0x77, F");
        asm("INCF 0X77,F");
       
        asm("MOVLW 0x64");
        asm("SUBWF 0x78, F"); //in_val
        asm("GOTO Loop1");
asm("Loop2:");
//        asm("MOVLW 0x1");
//        asm("MOVWF 0x74");
//        asm("MOVF 0x74, W");
//        asm("ADDWF 0x76, F");
        asm("INCF 0X76,F");
       
        asm("MOVLW 0xA");
        asm("SUBWF 0x78, F"); //in_val
asm("Skip1:");
        asm("MOVLW 0xA");
        asm("SUBWF 0x78, W"); //in_val
       
        asm("MOVLW 0xA");
        asm("SUBWF 0x78, W"); //in_val
        asm("BTFSC STATUS, 0x0");
        asm("GOTO Loop2");
       
        asm("MOVF 0x78, W"); //in_val
        asm("MOVWF 0x74");
        asm("MOVF 0x74, W");
        asm("ADDWF 0x75, F"); // digits

The generated code is one to one:
Code: [Select]
39:                    asm("MOVLW 0xFF");
0012  30FF     MOVLW 0xFF
40:                    asm("MOVWF 0x74");
0013  00F4     MOVWF 0x74
41:                    asm("MOVF 0x74, W");
0014  0874     MOVF 0x74, W
42:                    asm("MOVWF 0x78"); // in_val
0015  00F8     MOVWF 0x78
43:                   
44:                    asm("MOVLW 0x30");
0016  3030     MOVLW 0x30
45:                    asm("MOVWF 0x77");
0017  00F7     MOVWF 0x77
46:                    asm("MOVWF 0x76");
0018  00F6     MOVWF 0x76
47:                    asm("MOVWF 0x74");
0019  00F4     MOVWF 0x74
48:                    asm("MOVF 0x74, W");
001A  0874     MOVF 0x74, W
49:                    asm("MOVWF 0x75"); // digits
001B  00F5     MOVWF 0x75
50:            asm("Loop1:");
51:                    asm("MOVLW 0x64");
001C  3064     MOVLW 0x64
52:                    asm("SUBWF 0x78, W"); //in_val
001D  0278     SUBWF 0x78, W
53:                    asm("BTFSS STATUS, 0x0");
001E  1C03     BTFSS STATUS, 0x0
54:                    asm("GOTO Skip1");
001F  2827     GOTO 0x27
55:                   
56:            //        asm("MOVLW 0x1");
57:            //        asm("MOVWF 0x74");
58:            //        asm("MOVF 0x74, W");
59:            //        asm("ADDWF 0x77, F");
60:                    asm("INCF 0X77,F");
0020  0AF7     INCF 0x77, F
61:                   
62:                    asm("MOVLW 0x64");
0021  3064     MOVLW 0x64
63:                    asm("SUBWF 0x78, F"); //in_val
0022  02F8     SUBWF 0x78, F
64:                    asm("GOTO Loop1");
0023  281C     GOTO 0x1C
65:            asm("Loop2:");
66:            //        asm("MOVLW 0x1");
67:            //        asm("MOVWF 0x74");
68:            //        asm("MOVF 0x74, W");
69:            //        asm("ADDWF 0x76, F");
70:                    asm("INCF 0X76,F");
0024  0AF6     INCF 0x76, F
71:                   
72:                    asm("MOVLW 0xA");
0025  300A     MOVLW 0xA
73:                    asm("SUBWF 0x78, F"); //in_val
0026  02F8     SUBWF 0x78, F
74:            asm("Skip1:");
75:                    asm("MOVLW 0xA");
0027  300A     MOVLW 0xA
76:                    asm("SUBWF 0x78, W"); //in_val
0028  0278     SUBWF 0x78, W
77:                   
78:                    asm("MOVLW 0xA");
0029  300A     MOVLW 0xA
79:                    asm("SUBWF 0x78, W"); //in_val
002A  0278     SUBWF 0x78, W
80:                    asm("BTFSC STATUS, 0x0");
002B  1803     BTFSC STATUS, 0x0
81:                    asm("GOTO Loop2");
002C  2824     GOTO 0x24
82:                   
83:                    asm("MOVF 0x78, W"); //in_val
002D  0878     MOVF 0x78, W
84:                    asm("MOVWF 0x74");
002E  00F4     MOVWF 0x74
85:                    asm("MOVF 0x74, W");
002F  0874     MOVF 0x74, W
86:                    asm("ADDWF 0x75, F"); // digits
0030  07F5     ADDWF 0x75, F
« Last Edit: April 27, 2014, 06:33:27 am by miguelvp »
 

Offline amwales

  • Regular Contributor
  • *
  • Posts: 80
  • Country: gb
Re: C code and Assembly
« Reply #2 on: April 27, 2014, 02:33:09 pm »
Nothing constructive to say here.
The assembler side of XC8 is badly documented, you are not alone.
They should have provided a whole document in it's own right for the assembler, it looks like they really don't want you using it.
I even remember a discussion where a microchip engineer suggested looking at the C output to see how you should go about writing it since some features where not documented.
Don't give up, it's doable, the way I did it was to produce a .asm file with labels exported so they could be accessed from C, saving the state of any registers used and restoring them on exit.
 

Online linux-works

  • Super Contributor
  • ***
  • Posts: 1997
  • Country: us
    • netstuff
Re: C code and Assembly
« Reply #3 on: April 27, 2014, 02:41:05 pm »
of course, the proper way is not to put asm into C files.  that's pretty ugly and not the right way.

c could compile to a common linkable format and so should assem.  you assemble the .asm file to a .o, you compile the .c file to a .o and you link them together.

sounds like your tools are primitive (I don't know microchip, if that's what you are targeting).  adding assemb to c files is not the proper way to merge asm and c into a single binary.

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: C code and Assembly
« Reply #4 on: April 27, 2014, 02:43:34 pm »
Quote
what is the best way to combine assembly code into a c source code?

The best way to code in assembly is not to code in assembly: unless you know what you are doing and/or have  unlimited sources, assembly isn't the way to go.

If you insist, look into your compiler manual for more details.
================================
https://dannyelectronics.wordpress.com/
 

Offline marsalTopic starter

  • Newbie
  • Posts: 8
Re: C code and Assembly
« Reply #5 on: April 27, 2014, 09:56:37 pm »
so i went about using asm("blah blah") and it worked however its spitting out a syntax error. what is the deal with it?
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: C code and Assembly
« Reply #6 on: April 27, 2014, 10:03:03 pm »
Quote
it worked however its spitting out a syntax error.

Did it work or did it not work? That's the question, :)
================================
https://dannyelectronics.wordpress.com/
 

Offline marsalTopic starter

  • Newbie
  • Posts: 8
Re: C code and Assembly
« Reply #7 on: April 27, 2014, 10:05:35 pm »
well i am getting a syntax error so but i don't know why.. i guess that means it didnt work
 

Offline DrGeoff

  • Frequent Contributor
  • **
  • Posts: 794
  • Country: au
    • AXT Systems
Re: C code and Assembly
« Reply #8 on: April 27, 2014, 10:39:40 pm »
Write the assembly routines in assembly (.asm files), assemble to object code and then link it into your C program at the linker stage during project compilation. Writing blocks of assembler code in C files is not a good way to do things.
Was it really supposed to do that?
 

Offline Dinsdale

  • Regular Contributor
  • *
  • Posts: 77
  • Country: us
    • pretzelogic
Re: C code and Assembly
« Reply #9 on: May 01, 2014, 04:57:06 pm »
You should be able to enter assembly code as in this example. (This is not practical code, and the loop is just for illustrating labels)
Code: [Select]
#asm
here:
    movlw   0xff
    movwf   TRISA
    movwf   TRISB
    movwf   TRISC
    movlw   0x30
    movwf   PORTA
    bsf     STATUS, 5
    goto    here
#endasm
Using the preprocessor directives lets you write clearer code without all he asm("blah blah").
In-line assembly in a C file is OK, and sometimes necessary for speed reasons.  Large assembly sections may be better managed in a separate file.
I compiled the above on the command-line using xc8.
Your error display shows that there is an error on line 700-something, but that line is not on the display (at least as far as I can make out).
This can't be happening.
 

Offline madshaman

  • Frequent Contributor
  • **
  • Posts: 698
  • Country: ca
  • ego trans insani
Re: C code and Assembly
« Reply #10 on: May 01, 2014, 05:56:19 pm »

You should be able to enter assembly code as in this example. (This is not practical code, and the loop is just for illustrating labels)
Code: [Select]
#asm
here:
    movlw   0xff
    movwf   TRISA
    movwf   TRISB
    movwf   TRISC
    movlw   0x30
    movwf   PORTA
    bsf     STATUS, 5
    goto    here
#endasm
Using the preprocessor directives lets you write clearer code without all he asm("blah blah").
In-line assembly in a C file is OK, and sometimes necessary for speed reasons.  Large assembly sections may be better managed in a separate file.
I compiled the above on the command-line using xc8.
Your error display shows that there is an error on line 700-something, but that line is not on the display (at least as far as I can make out).

I agree (wrt inline asm), it also lets you keep a C version that performs the same function visually nearby that you can toggle between with an #if 0 or whatever floats your boat.
To be responsible, but never to let fear stop the imagination.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf