這是我用來在記憶體中寫入一些資料以進行除錯的代碼(直到 u-boot 程式中的 printf 可用)。變數myptr位于.__mydebug節中,每寫入 8 位元組后它會增加 8,我想以對的形式寫入任何我感興趣的值{debug_tag, debug_value}。這debug_tag是顯示除錯資料序列的一些值,這debug_value 是我在除錯期間要檢查(或查看)的值。這是 arm64 程式集。
.global myptr
ldr x28, =myptr /* load the address of myptr */
add x28, x28, #8 /* set write pointer to the next address after the myptr variable */
mov x27, #0x33 /* first debug write starts with tag value 0x33 */
str x27, [x28], #8 /* write the tag value, increment the pointer */
mov x27, some_value /* some_value : the value I want to see with tag value 0x33 */
str x27, [x28], #8 /* write the debug value, increment the pointer */ ldr x26, =myptr /* load pointer address */
/* next debug write, in the same assembly code, x28 hasn't changed, so use as is */
mov x27, #0x34 /* new debug tag */
str x27, [x28], #8 /* write new tag, increment pointer */
mov x27, some_another_value /* another data I want to check */
str x27, [x28], #8 /* write the data, increment pointer */
ldr x26, =myptr /* load the address of myptr to x26 */
str x28, [x26] /* save the updated pointer in myptr, just in case x28 is modified and \
the pointer should be used later in assembly or C code .. */
.... (skip) ....
.section .__mydebug
myptr: .double 0x0
data_start: .double 0x0
所以這是在作業的記憶體部分中順序寫入除錯資訊。
我可以稍后在 .c 程式中繼續此除錯寫入,如下所示,它也可以作業。
// debug print
int xx=sizeof(struct global_data);
*((uint64_t *)myptr) = 0x101; myptr =8; /* debug tag start with 0x101 here */
*((uint64_t *)myptr) = xx; myptr =8; /* write some data I want to check.. */
*((uint64_t *)myptr) = 0x102; myptr =8; /* another debug tag */
*((uint64_t *)myptr) = base; myptr =8; /* another value I want to check */
好吧,我可以忍受。但這看起來不好看也不方便。
所以我很好奇如何使用帶有行內匯編的函式在 C 程式中執行上述操作。我想將標記值和除錯值(64 位)作為引數傳遞給函式。該函式應檢索myptr值以寫入標簽和資料,并應myptr每次更新該值。我試著在下面寫一個函式。
void dbg_print(unsigned int tag, uint64_t data)
{
uint64_t ptr_addr1;
__asm (
"ldr %[ptr_addr], =myptr" \
"ldr %[ptr_val], [%[ptr_addr]]" \
"str %[tag_val], [%[ptr_val]], #8" \
"str %[data_val], [%[ptr_val]], #8"
: /* no output */ \
: [tag_val] "r" (tag), [data_val] "r" (data) /* input list */ \
: "memory" /* no specific clobbered register, but memory modified */
);
}
當我編譯它時,我收到這個編譯錯誤。
common/init/board_init.c: In function 'dbg_print':
common/init/board_init.c:144:1: error: undefined named operand 'ptr_addr'
144 | );
| ^
common/init/board_init.c:144:1: error: undefined named operand 'ptr_val'
common/init/board_init.c:144:1: error: undefined named operand 'ptr_addr'
common/init/board_init.c:144:1: error: undefined named operand 'ptr_val'
common/init/board_init.c:144:1: error: undefined named operand 'ptr_val'
make[2]: *** [scripts/Makefile.build:254: spl/common/init/board_init.o] Error 1
make[1]: *** [scripts/Makefile.spl:515: spl/common/init] Error 2
I can't understand undefined named operand error. Do I need to define the operand in the template somewhere? In the example in https://www.keil.com/support/man/docs/armclang_ref/armclang_ref_qbn1517569205870.htm, the operands in the template are just used without defining. The variables in C is declared anyway but aren't the operands in the assembly template substituted by the compiler anyway?
Thank you for reading and I would be grateful if someone could clarify this thing to me.
ADD :
Having read Nate Eldredge and Peter Cordes's comments, I realized 'defining the operand' means to connect the value into the C world using the operand specifiers (those fields after : and connected with :). So I tried changing the code to this and I'll see if this works.
void dbg_print(unsigned int tag, uint64_t data)
{
uint64_t ptra, ptrv;
__asm (
"ldr %[ptr_addr], =myptr \n" /* get pointer address */
"ldr %[ptr_val], [%[ptr_addr]] \n" /* get pointer value */
"str %[tag_val], [%[ptr_val]], #8 \n" /* write to pointed addr */
"str %[data_val], [%[ptr_val]], #8 \n" /* write to pointed addr */
: [ptr_addr] "=r" (ptra), [ptr_val] "=r" (ptrv)
: [tag_val] "r" (tag), [data_val] "r" (data) /* input list */
: "memory" /* no specific clobbered register, but memory modified */
);
}
uj5u.com熱心網友回復:
我無法理解未定義的命名運算元錯誤。我需要在模板中的某處定義運算元嗎?在https://www.keil.com/support/man/docs/armclang_ref/armclang_ref_qbn1517569205870.htm 中的示例中,模板中的運算元只是使用而不定義。
是的,您需要在 asm 陳述句的輸入或輸出中定義它們。您鏈接的所有示例都定義了它們使用的所有名稱。您的代碼只是定義了tag_val并且data_val在那里,因此ptr_val和ptr_addr未定義。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/384837.html
標籤:assembly gcc inline-assembly arm64
下一篇:存盤器組件中的開關輸入位置
