avr-gcc - bit-operation tar 3 instruktioner

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

avr-gcc - bit-operation tar 3 instruktioner

Inlägg av bearing »

Märkte när jag lade till följande kod att binärfilen blev 10(!) bytes större. Detta borde väl ta endast en instruktion?

Kod: Markera allt

UCSR0B |= (1<<TXEN0);
lst-filen visar följande:

Kod: Markera allt

    UCSR0B |= (1<<TXEN0);
    1ada:	80 91 c1 00 	lds	r24, 0x00C1
    1ade:	88 60       	ori	r24, 0x08	; 8
    1ae0:	80 93 c1 00 	sts	0x00C1, r24
Finns det något annat sätta att skriva C-koden på så att avr-gcc förstår att den endast ska använda instruktionen som sätter en enskild bit?
Senast redigerad av bearing 29 oktober 2008, 22:38:56, redigerad totalt 1 gång.
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Hmm, det verkar som att det här registret är placerat på olika ställen i olika AVR-er.

Jag använder ATMega88:

Kod: Markera allt

iomx8.h:591:	#define UCSR0B  _SFR_MEM8 (0xC1)
I en annan AVR:

Kod: Markera allt

ATMega8. iom8.h:74:	#define UCSRB	_SFR_IO8(0x0A)
Jag är inte så insatt i instruktionsuppsättningen, men jag antar att detta betyder att bit-operationen inte går att utföra mot "MEM8"-register, fast mot "IO8"-register.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Om du tittar på bit-instruktionerna så ser du att adressen i själva
instruktionen (som pekar mot aktuellt register) har en begränsad
adressarea. Det gör att bit-instruktioner (t.ex, det finns även andra)
inte fungerar mot alla register, vilka vet man bara om man kollar
upp respektive registers adress. Atmel har exempel (i assembler)
där man använder macron som väljer olika instruktioner beroende på
registrets adress.

Om det är så att vissa register är flyttade mellan olika modeller så
att de hamnar på den ena sidan om gränsen eller den andra, så
behövs dessa macron för att göra koden flyttbar mellan dom.

Om detta har med MEM8/IO8 att göra (eller vad det är) vet jag dock inte...
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Inlägg av bearing »

Aha, då förstår jag. Ja, det är klart att de inte har möjlighet att lägga så stora adresser där om det ska vara möjligt att skapa många instruktioner.

Hittade en kommentar om det här i databladet, samt avr-lib definitionen av makrona.

Kod: Markera allt

2. I/O Registers within the address range 0x00 - 0x1F are directly bit-accessible using the SBI and CBI instructions. In these
registers, the value of single bits can be checked by using the SBIS and SBIC instructions.
...
4. When using the I/O specific commands IN and OUT, the I/O addresses 0x00 - 0x3F must be used. When addressing I/O
Registers as data space using LD and ST instructions, 0x20 must be added to these addresses. The ATmega48/88/168 is a complex
microcontroller with more peripheral units than can be supported within the 64 location reserved in Opcode for the IN
and OUT instructions. For the Extended I/O space from 0x60 - 0xFF in SRAM, only the ST/STS/STD and LD/LDS/LDD
instructions can be used.

Kod: Markera allt

#ifndef __SFR_OFFSET
/* Define as 0 before including this file for compatibility with old asm
   sources that don't subtract __SFR_OFFSET from symbolic I/O addresses.  */
#define __SFR_OFFSET 0x20
#endif

#if (__SFR_OFFSET != 0) && (__SFR_OFFSET != 0x20)
#error "__SFR_OFFSET must be 0 or 0x20"
#endif

#define _SFR_MEM8(mem_addr) (mem_addr)
#define _SFR_MEM16(mem_addr) (mem_addr)
#define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
#define _SFR_IO16(io_addr) ((io_addr) + __SFR_OFFSET)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Växtvärk, kan man väl säga.
Antagligen hade den ursprungliga AVR arkitekturen inte mer
än 64 I/O registers så då var det inget problem...
Skriv svar