Error: se requiere un valor constante al compilar con avr-as en linux

1

Estoy tratando de compilar el siguiente programa de ensamblaje simple pero hay un problema con el compilador que no puedo encontrar su razón y solucionarlo.

Así que aquí está el código:

  1 #define __SFR_OFFSET 0 
  2 #include <avr/io.h> 
  3 
  4 
  5 rjmp Init 
  6 
  7 .global Init 
  8 
  9 Init:   sbi _SFR_IO_ADDR(PORTB),5 
 10         rjmp In

y cuando voy a compilarlo con
avr-as -c -mmcu=atmega168a -o ledON.o ledON.s

estoy recibiendo este error:

ledON.s: Assembler messages:  
ledON.s:9: Error: constant value required
ledON.s:9: Error: ',' required  
ledON.s:9: Error: constant value required
ledON.s:9: Error: garbage at end of line

También cambio un poco el código como se puede ver arriba, pero todavía hay un error

  1 ;#define _SFR_OFFSET 0 
  2 #include <avr/io.h> 
  3 
  4 rjmp Init
  5 
  6 .global Init
  7 
  8 Init:   sbi PORTB,0x05
  9         rjmp Init
  

ledON.s: mensajes del ensamblador:

     

ledON.s: 8: Error: se requiere un valor constante

¿Alguna idea?

    
pregunta F.N

1 respuesta

4

Descubrí cómo ensamblar sin mensajes de error.

Los mensajes de error que ve son causados por el hecho de que avr-as no invoca el preprocesador C y, por lo tanto, las líneas #include se leen como comentarios regulares.

Cree un archivo ledON.S y observe el CAPITAL S en el nombre del archivo. El capital S indica que el preprocesador C debe invocarse primero. Crea el archivo con el siguiente contenido:

#include <avr/io.h> 

init:   sbi     _SFR_IO_ADDR(DDRB),0x05         ; Configure port B pin 5 as output
        ret

.global main

main:
        call init

loop:
        sbi     _SFR_IO_ADDR(PORTB),0x05        ; Toggle output pin HIGH
        cbi     _SFR_IO_ADDR(PORTB),0x05        ; Toggle output pin LOW
        rjmp loop

La parte main se requiere en el código fuente, aquí es donde generalmente se encuentra el programa principal. Si lo elimina, nunca se ejecutará ningún código real y, por lo tanto, el compilador se quejará de eso. El código en una rutina llamada init debe llamarse explícitamente desde main . Si bien el pin cambia, en la práctica esto será demasiado rápido para ver a simple vista. Si verifica con un osciloscopio, verá una onda cuadrada (estimo en un ciclo de trabajo del 25%).

Luego arme el código fuente con:

avr-gcc -mmcu=atmega168a ledON.S -o ledON.o

De nuevo, se requiere avr-gcc para invocar el preprocesador C

.

Para verificar el resultado del programa ensamblado, ejecute el siguiente comando:

avr-objdump -C -d ./ledON.o

Y el listado de desmontaje resultante se ve así:

./ledON.o:     file format elf32-avr


Disassembly of section .text:

00000000 <__vectors>:
   0:   0c 94 34 00     jmp     0x68    ; 0x68 <__ctors_end>
   4:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
   8:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
   c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  10:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  14:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  18:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  1c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  20:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  24:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  28:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  2c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  30:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  34:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  38:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  3c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  40:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  44:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  48:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  4c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  50:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  54:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  58:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  5c:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  60:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>
  64:   0c 94 3e 00     jmp     0x7c    ; 0x7c <__bad_interrupt>

00000068 <__ctors_end>:
  68:   11 24           eor     r1, r1
  6a:   1f be           out     0x3f, r1        ; 63
  6c:   cf ef           ldi     r28, 0xFF       ; 255
  6e:   d4 e0           ldi     r29, 0x04       ; 4
  70:   de bf           out     0x3e, r29       ; 62
  72:   cd bf           out     0x3d, r28       ; 61
  74:   0e 94 42 00     call    0x84    ; 0x84 <main>
  78:   0c 94 47 00     jmp     0x8e    ; 0x8e <_exit>

0000007c <__bad_interrupt>:
  7c:   0c 94 00 00     jmp     0       ; 0x0 <__vectors>

00000080 <init>:
  80:   25 9a           sbi     0x04, 5 ; 4
  82:   08 95           ret

00000084 <main>:
  84:   0e 94 40 00     call    0x80    ; 0x80 <init>

00000088 <loop>:
  88:   2d 9a           sbi     0x05, 5 ; 5
  8a:   2d 98           cbi     0x05, 5 ; 5
  8c:   fd cf           rjmp    .-6             ; 0x88 <loop>

0000008e <_exit>:
  8e:   f8 94           cli

00000090 <__stop_program>:
  90:   ff cf           rjmp    .-2             ; 0x90 <__stop_program>
  

INTERMEZZO

     

Notarás que el ensamblador inicializará automáticamente el puntero de pila   y registro de estado en __ctors_end .   También agregará automáticamente un rjmp al final del código.   El comportamiento predeterminado de un programa ensamblado por gcc-avr cuando finaliza es:

     
  • desactivar las interrupciones ( _exit , cli )
  •   
  • bucle vacío infinito que no hace nada ( __stop_program , rjmp .-2 )
  •   
    
respondido por el jippie

Lea otras preguntas en las etiquetas