Avr-g++ — неопределенная ссылка на регистр Y при связыванииC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Avr-g++ — неопределенная ссылка на регистр Y при связывании

Сообщение Anonymous »

У меня возникла странная проблема при выполнении встроенного ассемблера и компиляции/компоновки с помощью avr-g++ (версия 16, только что из Git). Я думаю, что это может быть ошибка в цепочке инструментов, но мне хотелось бы получить второе мнение на случай, если я просто чего-то не вижу.
Вот минимальный фрагмент кода, который мне удалось придумать, который не работает:

Код: Выделить всё

int main() {
unsigned char value = 10;
asm volatile(
"lds r12, %0"
:: "m" (value)
: "r12");
return 0;
}
При компиляции ничего особенного не происходит; но при связывании я получаю это странное сообщение об ошибке (это именно та команда, которую я использую для создания своего эльфа):

Код: Выделить всё

> avr-g++ -std=gnu++20 -DF_CPU=20000000L -g -Wall -Wextra -fdata-sections -mmcu=avr128da28 -Os -c mwe.cpp -o mwe.o
> avr-g++ -mrelax -Wl,--gc-sections -mmcu=avr128da28 -Os mwe.o -o mwe.elf
/usr/lib/gcc/avr/16.0.0/../../../../avr/bin/ld: mwe.o: in function `.Loc.3':
.../tests/mwe.cpp:26:(.text.startup+0xc): undefined reference to `Y'
collect2: error: ld returned 1 exit status
(Редактировать: для справки, l. 26 точно соответствует lds r12, %0; файл также содержит некоторый закомментированный код, здесь не имеющий значения)
Ни один эльф не создается; Я попытался выполнить objdump mwe.o:

Код: Выделить всё

> avr-objdump -s -d mwe.o
...
Disassembly of section .text.startup:

00000000 :
0:   0f 92           push    r0
2:   cd b7           in  r28, 0x3d   ; 61
4:   de b7           in  r29, 0x3e   ; 62

00000006 :
6:   8a e0           ldi r24, 0x0A   ; 10
8:   89 83           std Y+1, r24    ; 0x01

0000000a :
a:   c0 90 00 00     lds r12, 0x0000 ; 0x800000 

0000000e :
e:   80 e0           ldi r24, 0x00   ; 0
10:   90 e0           ldi r25, 0x00   ; 0
12:   0f 90           pop r0
14:   08 95           ret
Я не вижу ничего особенно странного... Компоновщик говорит, что проблема в .text.startup+0xc, но это будет в середине инструкции lds, я не понимаю почему...
Что вызывает ошибку?
Изменить: коллега попросил меня сгенерировать ассемблер с -S, и я думаю, мы видим виновника здесь:

Код: Выделить всё

...
.L__stack_usage = 1
.loc 1 23 5 view .LVU1
.loc 1 23 19 is_stmt 0 view .LVU2
ldi r24,lo8(10)
std Y+1,r24
.loc 1 24 5 is_stmt 1 view .LVU3
/* #APP */
;  24 "mwe.cpp" 1
lds r12, Y+1
;  0 "" 2
.loc 1 28 5 view .LVU4
.loc 1 29 1 is_stmt 0 view .LVU5
/* #NOAPP */
ldi r24,0
ldi r25,0
...
У нас Y появляется в качестве второго операнда lds, что действительно неверно (я думаю). Кажется, что компоновщик воспринимает это как символ. Это подтверждается запуском nm:

Код: Выделить всё

> nm mwe.o
00000034 a __CCP__
00000000 t L0
00000016 t L0
00000016 t L0
00000000 N L0
00000000 N .Ldebug_abbrev0
00000000 N .Ldebug_info0
00000000 N .Ldebug_line0
00000000 t .LFB0
00000016 t .LFE0
0000000c N .LLRL0
00000000 t .Loc.0
00000006 t .Loc.1
00000006 t .Loc.2
0000000a t .Loc.3
0000000e t .Loc.4
0000000e t .Loc.5
00000000 T main
0000003b a __RAMPZ__
0000003e a __SP_H__
0000003d a __SP_L__
0000003f a __SREG__
00000000 a __tmp_reg__
U Y
00000001 a __zero_reg__
Теперь вопрос в том, зачем здесь использовать регистр Y...

Подробнее здесь: https://stackoverflow.com/questions/798 ... on-linking
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»