> From: Mike Harrison [mailto:mike@whitewing.co.uk] ... >>> char reverse_bits(char source)// reverses bits 0 to 6 - >>> source = 0ABCDEFG >>> { >>> char result; >>> #asm >>> swapf _source,w ;W= DEFG0ABC >>> btfsc _source,3 ; If D = 1, >>> xorlw 0x88 ;convert now sure W= 0EFGDABC >>> >>> btfsc _source,6 ;Test bit A >>> xorlw 0x05 ;Invert bits A and C >>> btfsc _source,4 ;Test bit C >>> xorlw 0x05 ;Invert bits A and C >>> ;now W = 0EFGDCBA >>> btfsc _source,2 ;Do the same with E and G >>> xorlw 0x50 >>> btfsc _source,0 >>> xorlw 0x50 >>> movwf _result ;so now W = 0GFEDCBA (done) >>> #endasm >>> return(result); >>> } >>> >>> But, on building, the linker says that _source and _result >>> are undefined variables. I thought that, to use a C variable >>> in a piece of assembler code, you simply prepend an >>> underscore to it. Anyone know what I'm doing wrong? Global variables usually use underscores local variables are of the format ?a_procedurename + offset > I found that Hi-Tech had a nasty habit of optimising out vars that > were only used inside ASM blocks. > I can't remember If I found a solution to this situation for return > vars. > I think doing something like > result=result; > outside the #asm can fix it, but can also generate unnecessary code. In this case, since result is returned, it didn't get optimized out. source was the one that was lost, so you would have to add a line like result = source; However, you can also cheat a bit. Result is only used to return the end result. There's no reason that source can't be used for that. This way no extra code is added. In assembly language this kind of cheating could effect some variable outside of the function, but in C, source is just the value of the variable in the calling function, it stops being a meaningful reference once this function exits anyway, so it's okay to stomp on. The code at the bottom is what I came up with. If you really want to use result, you can start the function with the line: source = (source << 4) | (source >> 4) that will generate: swapf ?a_reverse_bits start the asm with movf ?a_reverse_bits, w change all the bit tests to handle the swap, and end the code with movwf ?a_reverse_bits+1 /* Converts 0ABCDEFG to 0GFEDCBA */ char reverse_bits(char source) { #asm ;source is ?a_reverse_bits swapf ?a_reverse_bits, w ;W = DEFG0ABC btfsc ?a_reverse_bits, 3 ;If D = 1, xorlw 0x88 ;Now we're sure W = 0EFGDABC btfsc ?a_reverse_bits, 6 ;Test bit A xorlw 0x05 ;Invert bits A and C btfsc ?a_reverse_bits, 4 ;Test bit C xorlw 0x05 ;Invert bits A and C ;now W = 0EFGDCBA btfsc ?a_reverse_bits, 2 ;Do the same with E and G xorlw 0x50 btfsc ?a_reverse_bits, 0 xorlw 0x50 movwf ?a_reverse_bits ;so now W = 0GFEDCBA, copy to source #endasm return(source); } -- http://www.piclist.com hint: The PICList is archived three different ways. See http://www.piclist.com/#archives for details.