Загрузка переменных адресов в регистры PowerPC inline Assembly - PullRequest
1 голос
/ 01 октября 2019

Я пытаюсь собрать пример кода встроенного ассемблера в программе «C». У меня не было никакого успеха. Я использую GCC 4.9.0. Насколько я могу судить, мой синтаксис правильный. Однако сборка взрывается со следующими ошибками:

/tmp/ccqC2wtq.s:48: Error: syntax error; found `(', expected `,'
Makefile:51: recipe for target 'all' failed
/tmp/ccqC2wtq.s:48: Error: junk at end of line: `(31)'
/tmp/ccqC2wtq.s:49: Error: syntax error; found `(', expected `,'
/tmp/ccqC2wtq.s:49: Error: junk at end of line: `(9)'

Они связаны со строками ввода / вывода / замыкания в коде. У кого-нибудь есть идеи, где я ошибся?

  asm volatile("li 7, %0\n"           // load destination address
               "li 8, %1\n"           // load source address

               "li 9, 100\n"              // load count

               // save source address for return
               "mr   3,7\n"

               // prepare for loop
               "subi 8,8,1\n"
               "subi 9,9,1\n"

               // perform copy
               "1:\n"
               "lbzu 10,2(8)\n"

               "stbu 10,2(7)\n"
               "subi 9,9,1\n"              // Decrement the count
               "bne  1b\n"          // If zero, we've finished

               "blr\n"

               : // no outputs
               : "m" (array), "m" (stringArray)
               : "r7", "r8"
               );

Ответы [ 2 ]

2 голосов
/ 01 октября 2019

Непонятно, что вы пытаетесь сделать с начальными инструкциями:

li 7, %0
li 8, %1

Вы хотите загрузить адрес переменных в эти регистры? В общем случае это невозможно, поскольку адрес не может быть представлен в непосредственном операнде. Самый простой выход - избегать использования r7 и r8, а вместо этого использовать% 0 и% 1 напрямую в качестве имен регистров. Похоже, что вы хотите использовать эти регистры в качестве базовых адресов, поэтому вы должны использовать ограничение b:

               : "b" (array), "b" (stringArray)

Тогда GCC позаботится о деталях материализации адреса подходящим способом.

Вы не можете вернуться, используя blr из встроенного ассемблера, потому что невозможно разрушить созданный GCC кадр стека. Вам также необходимо дважды проверить клобберы и убедиться, что вы перечислили все кобберы (включая коды условий, память и перезаписанные входные операнды).

0 голосов
/ 02 октября 2019

Я смог добиться этого, объявив пару указателей и инициализировав их адресами массивов. Я не понимал, что адреса не будут доступны напрямую. В прошлом я очень редко использовал встроенную сборку, обычно просто для того, чтобы поднимать или опускать маски прерываний, а не делать что-либо, ссылающееся на переменные. У меня просто были люди, которые хотели пример. И «blr» остался, когда я скопировал фрагмент чистой процедуры сборки для использования в качестве отправной точки. Спасибо за ответы. Окончательный фрагмент кода выглядит следующим образом:

int main()
{
    char * stringArrayPtr;
    unsigned char * myArrayPtr;

    unsigned char myArray[100];

    stringArrayPtr = (char *)&stringArray;
    myArrayPtr     = myArray;

    asm volatile(
                 "lwz 7,%[myArrayPtr]\n"       // load destination address
                 "lwz 8, %[stringArrayPtr]\n"  // load source address

                 "li 9, 100\n"                 // load count
                 "mr 3,7\n"                    // save source address for return

                 "subi 8,8,1\n"                // prepare for loop
                 "subi 9,9,1\n"

                 "1:\n"                        // perform copy
                 "lbzu 10,1(8)\n"
                 "stbu 10,1(7)\n"
                 "subic. 9,9,1\n"              // Decrement the count
                 "bne  1b\n"                   // If zero, we've finished

                 // The outputs / inputs / clobbered list
                 // No output variables are specified here
                 // See GCC documentation on extended assembly for details.
                 : 
                 : [stringArrayPtr] "m" (stringArrayPtr), [myArrayPtr]"m"(myArrayPtr)
                 : "7","8","9","10"
                 );
}
...