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

Estoy tratando de compilar el siguiente programa de ensamblaje simple, pero hay un problema con el compilador que no puedo encontrar el motivo 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: valor constante requerido

¿Algunas ideas?

¿Qué versión avr-asestás usando, la mía no es compatible con la -cbandera, qué hace?
Incluso sin -cla bandera, obtengo el mismo error: s
Claramente, los archivos de inclusión no se procesan en absoluto, ahora solo para descubrir cómo es eso.
¿Y dónde mirar para determinar eso? ¿Puedes darme alguna pista?
He estado experimentando un poco y claramente los archivos de inclusión no se procesan. Tiene que ver con el hecho de que as no llama al preprocesador C, pero no sé cómo forzar los archivos que se procesan

Respuestas (1)

Descubrí cómo ensamblar sin mensajes de error.

Los mensajes de error que ve se deben al hecho de que avr-asno invoca el preprocesador C y, por lo tanto, las #includelíneas se leen como comentarios normales.

Cree un archivo ledON.Sy observe las MAYÚSCULAS Sen el nombre del archivo. La mayúscula Sindica que primero se debe invocar el preprocesador C. Cree 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 mainparte se requiere en el código fuente, aquí es donde generalmente se encuentra el programa principal. Si lo elimina, nunca se ejecuta ningún código real y, por lo tanto, el compilador se quejará de eso. El código de una rutina llamada initdebe llamarse explícitamente desde main. Aunque el pin cambia, en la práctica esto será demasiado rápido para verlo a simple vista. Si verifica con un osciloscopio, verá una onda cuadrada (estimo en un ciclo de trabajo del 25%).

Luego ensamble el código fuente con:

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

Nuevamente avr-gccse requiere invocar el preprocesador C.

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

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

Y la lista 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á que el ensamblador inicializará automáticamente el puntero de la pila y el registro de estado en __ctors_end. También agregará automáticamente una rjmpal 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)
Sí. Ya probé el .S pero una vez más me devuelve un error y no crea el archivo objeto. ledON.S: Assembler messages: ledON.S:8: Error: number must be positive and less than 32tales errores creo que eso significa que el registro de E/S no es editable.
Copie la fuente exacta como en mi respuesta y trabaje desde allí. Mi fuente propuesta se basa en mi sistema; de lo contrario, no podría mostrarle la lista de desmontaje.
DE ACUERDO. el archivo de objeto ahora se creó, pero ¿por qué sucede todo esto? No puedo entender. Además, en su código, rjmp to main nunca se ejecutará porque hay un bucle infinito de init arriba. Por cierto, no puedo votar porque soy un usuario nuevo y no tengo reputación.
Bastante justo, eliminé el último rjmp. La mainetiqueta es una parte requerida del programa, si la elimina, recibirá un mensaje de error. Normalmente ahí es donde se encuentra el programa principal.
@FN Actualicé la respuesta para reflejar una prueba de concepto algo útil.
Sí lo vi. Lo compilé, lo vinculé y lo probé. Led funcionó. Muchas gracias. Entonces, el problema está en el ensamblador, pero ¿crees que hay una manera de solucionarlo o no?
Según la documentación, así es como funciona. Desea que se invoque el preprocesador C, luego llame a gcc.
pero este tipo aquí? ¿Cómo lo hizo funcionar con avr-as? avr-as
@FN No sé. Sin embargo, las cosas han cambiado desde el 8 de abril de 2008. La cadena de herramientas tiene versiones principales completamente diferentes (el primer dígito del número de versión). Bajo el agua te avr-gccllama .avr-as
@FN Tenga en cuenta también que ese ejemplo no requiere la inclusión de los archivos de encabezado C.
Sí lo tengo. De todos modos. Probaré otras cosas y si encuentro algo te informaré :) Muchas gracias una vez más.