AVR-GCC Inline Assembler

AVR-GCC Inline Assembler

COMP 4550 AVR-GCC Inline Assembler Autonomous Agents Lab, University of Manitoba [email protected] http://www.cs.umanitoba.ca/~jacky http://aalab.cs.umanitoba.ca AVR-GCC Application Binary Interface (ABI) ● Data types: ○ char is 8 bits, ○ int is 16 bits, ○ long is 32 bits, ○ long long is 64 bits, ○ float and double are 32 bits (this is the only supported floating point format) ● include <inttypes.h> for uint16_t, ... ● Pointers are 16 bits ● Function pointers are word addresses, ○ to allow addressing the whole 128K program memory space on the ATmega devices with > 64 KB of flash ROM). ● -mint8 option (see Options for the C compiler avr-gcc) to make int 8 bits, not supported AVR-GCC Application Binary Interface (ABI) ● Call-saved registers (r2-r17, r28-r29): ○ May be allocated by gcc for local data. Calling C subroutines leaves them unchanged. Assembler subroutines are responsible for saving and restoring these registers, if changed. r29:r28 (Y pointer) is used as a frame pointer (points to local data on stack) if necessary. ● Call-used registers (r18-r27, r30-r31): ○ May be allocated by gcc for local data. You may use them freely in assembler subroutines. Calling C subroutines can clobber any of them - the caller is responsible for saving and restoring. AVR-GCC Application Binary Interface (ABI) ● Fixed registers (r0, r1): ● Never allocated by gcc for local data, but often used for fixed purposes: ● r0 - temporary register, can be clobbered by any C code (except interrupt handlers which save it), may be used to remember something for a while within one piece of assembler code ● r1 - assumed to be always zero in any C code, may be used to remember something for a while within one piece of assembler code, but must then be cleared after use (clr r1). This includes any use of the [f]mul[s[u]] instructions, which return their result in r1:r0. ● Interrupt handlers save and clear r1 on entry, and restore r1 on exit (in case it was non-zero). AVR-GCC Application Binary Interface (ABI) ● Function call conventions: ● Arguments - allocated left to right, r25 to r8. All arguments are aligned to start in even-numbered registers (odd-sized arguments, including char, have one free register above them). This allows making better use of the movw instruction on the enhanced core. ● If too many, those that don't fit are passed on the stack ● Return values: ● 8-bit in r24 (not r25!), 16-bit in r25:r24, up to 32 bits in r22- r25, up to 64 bits in r18-r25. 8-bit return values are zero/sign-extended to 16 bits by the caller (unsigned char is more efficient than signed char - just clr r25). Arguments to functions with variable argument lists (printf etc.) are all passed on stack, and char is extended to int. AVR-GCC asm Instruction ● asm introduces inline asm("\n\ assembler mov %0, %1 \n\ ● Assembly code is single lsr %0\n\ string constant " : "=r" (result) ● Use line continuation to : "r" (value) format ● %0,%1 correspond to ); pseudo registers, which are mapped by the compiler ● Correspond to input, output, clobber registers ● List of output operands (e.g., result) ● List of input operands (e.g., value) General Form ● General form ○ asm(code : output operand list : input operand list : clobber list); ● Input ○ registers that provide values to your code ● Output ○ registers that specify result of your expression ● Clobber ○ registers that are changed because of your code, outputs are always clobbered Volatile ● asm volatile instructs the compiler not to do any optimizations ● Must have at least two colons ● clobber list may be left off ● Special registers ● __SREG__(PORTE) - Port ● __SP_H__,__SP_L__ - Stack pointer ● __tmp_reg__ - R0 tmp variable, no need to restore ● __zero_reg__ - R1 always 0 asm volatile("cli"::); Register Constraints ● a simple upper register R16 to R23 ● b base pointer pair, y,z ● d upper register R16 to R31 ● e pointer register pairs x,y,z ● G floating point constant ● I,J 6 bit positive/negative constant ● t – temporary register ● K/L/N/O/P integer constants 0/2/-1/8,16,24/1 ● w – special upper reg ● l lower register ● x/y/z – pointer x,y,z ● M 8 bit constant ● q Stack pointer register SPH:SPL ● r Any register AVR-GCC Inline Assembler ● Read/write register values ● Can specify a digit to refer to previous register ○ asm volatile("swap %0" : "=r" (value) : "0" (value)); ● Read only registers asm volatile("in %0,%1\n\t" "out %1, %2\n\t" : "=&r" (input) : "I" (_SFR_IO_ADDR(port)), "r" (output)); Register Swap asm volatile("\t mov __tmp_reg__, %A0\n\" "\t mov %A0, %B0\n\" "\t mov %B0, __tmp_reg__\n\" ● 16 bit swap : "=r" (value) ○ %A0 upper 16 bit : "0" (value) ○ %B0 lower 16 bit ); ● 32 bit swap asm volatile("\t mov __tmp_reg__, %A0\n\" ○ %A0..%D0 "\t mov %A0, %D0\n\" ○ %A1..%D1 "\t mov %D0, __tmp_reg__\n\" "\t mov __tmp_reg__, %B0\n\" "\t mov %B0, %C0\n\" "\t mov %C0, __tmp_reg__\n\" : "=r" (value) : "0" (value) ); X,Y,Z Pointers ● Register pairs X,Y,Z are specified by the “e” constraint ● Z %A0=R30, %B0=R31 ● How to create the original register pair ○ ld r24,Z ○ ld r24, %a0 ; Note lower case “a” Clobber Registers ● Clobbers specify registers that are modified ● Atomic increment ● No input operand asm volatile( "\t cli\n\" ● Synchronization "\t ld r24, %a0\n\" ○ store value in memory "\t inc r24\n\" ● Better to use __tmp_reg__ "\t st %a0, r24\n\" ● Specify R24 as clobbered "\t sei\n" : ● Memory clobbers : "e" (ptr) ● *ptr is also changed : "r24" ● special clobber “memory” ); ○ will reload everything ● Better specify ptr as volatile Labels ● C Stub functions to hold temporary variables etc. ● L_dl1%= creates label void delay(uint8_t ms) { uint16_t cnt; ● cnt used as tmp reg asm volatile ( ● Can also unix label syntax "L_dl1%=:\n\" ● 1:/2: brne 2b "\t mov %A0, %A2\n\" "\t mov %B0, %B2\n\" "L_dl2%=:\n\" "\t sbiw %A0, 1\n\" "\t brne L_dl2%=\n\" "\t dec %1\n\" "\t brne L_dl1%=\n\" : "=&w" (cnt) : "r" (ms), "r" (delay_count) ); } Names ● Names used by the assembler can be defined by the C program ○ unsigned long value asm("clock") = 3686400; ● C uses value, assembler uses clock ● Specify register ○ register unsigned char counter asm("r3"); ● Functions ○ extern long Calc(void) asm ("CALCULATE"); .

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    15 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us