Проблема встроенной сборки GNU - PullRequest
3 голосов
/ 29 ноября 2010

Я провел некоторый рефакторинг для c167 кода, специфичного для платформы, и наткнулся на проблему со встроенной сборкой.

Предыдущий код:

  asm volatile ( "
            extp   #pag:%0, #3
            mov    r4, pof:%0   @ R4 = g_nRcvBufCount
            sub    r4, #1       @ R4 = R4 - 1
            mov    pof:%0, r4   @ g_nRcvBufCount = R4"
        : "=m" (g_nRcvBufCount)
        :
        : "r4"
  );

[

В основном этот код выполняет атомарный декремент переменной "g_nRcvBufCount"

Инструкция "extp" принимает "страницу" переменной "g_nRcvBufCount" и количество следующих атомных выражений (в данном случае 3)

]

Текущий - код не компилируется:

  asm volatile ( "
            extp   #pag:%0, #3
            mov    r4, pof:%0   @ R4 = cfg->g_nRcvBufCount
            sub    r4, #1       @ R4 = R4 - 1
            mov    pof:%0, r4   @ cfg->g_nRcvBufCount = R4"
        : "=m" (cfg->g_nRcvBufCount)
        :
        : "r4"
  );

где cfg - указатель на структуру, содержащую переменную "g_nRcvBufCount".

struct {
  ...
  unsigned short g_nRcvBufCount;
  ...
}cfg;

Ошибки, полученные при компиляции:

test.c:1124:Warning:Missing operand value assumed absolute 0. 
test.c:1124:extp #pag:[r2+#66],#3: trailing chars after expression    
test.c:1125:Warning:Missing operand value assumed absolute 0. 
test.c:1125:mov r4,pof:[r2+#66]: trailing chars after expression   
test.c:1127:Warning:Missing operand value assumed absolute 0. 
test.c:1127:mov pof:[r2+#66],r4: trailing chars after expression

Любые советы о том, как сделать эту работу, приветствуются.Также была бы полезна версия x86 (встроенной сборки) о том, как получить доступ к переменным, определенным в структуре C / C ++.Документация встроенного ассемблера GNU, объясняющая, что делает ключевое слово "= m", также полезна.

Заранее спасибо,

Iulian

Ответы [ 2 ]

2 голосов
/ 29 ноября 2010

Посмотрите на asm в предупреждающем сообщении:

extp #pag:[r2+#66],#3

Очевидно, что вещь #pag: действительна с регистром или абсолютным адресом после нее, но не с более сложным выражением, уже содержащим смещение, подобное[r2+#66].Возможно, вам придется переключиться на использование аргумента "r", содержащего адрес cfg->g_nRcvBufCount вместо аргумента "m", ссылающегося на него.

В этом случае обратите внимание, чтоисходный код был поддельным для начала и работал только потому, что gcc решил заменить простое адресное выражение, которое работало в asm.

1 голос
/ 29 ноября 2010

из там же

"m": разрешен операнд памяти с любым типом адреса, который аппарат в целом поддерживает.

об "ошибках" - это "только" предупреждения - попробуйте создать небольшой файл .c с этой сборкой, разобрать его и посмотреть, как его выводит objdump это может дать вам подсказку о том, как редактировать код, чтобы эти предупреждения не отображались

...