簡體   English   中英

GCC內聯匯編常量(ARM)

[英]GCC inline assembly constants (ARM)

有沒有一種好的方法可以將內聯匯編代碼的常量作為“參數”? 我正在嘗試使協處理器訪問功能。 我嘗試了兩種方法:宏替換和擴展。

用法是這樣的:

unsigned int read_ID_PFR1()
{
    READ_CP15(0, 0, 1, 1);
    return cp_reg_val;
}

宏方法:

#define READ_CP15(opc, crn, crm, opc2) \
asm volatile (\
    "push {r0, r1}\n\t"\
    "mrc p15, opc, r0, crn, crm, opc2\n\t"\
    "ldr r1, =cp_reg_val\n\t"\
    "str r0, [r1]\n\t"\
    "pop {r0, r1}\n\t"\
    )

我認為參數(opc,crn,...)沒有擴展,因為它們在引號內使用。

擴展方法如下所示:

#define WRITE_CP15(opc, crn, crm, opc2) \
    asm volatile (\
        "push {r0, r1}\n\t"\
        "ldr r1, =cp_reg_val\n\t"\
        "ldr r0, [r1]\n\t"\
        "mcr p15, %[op], r0, c%[rn], c%[rm], %[op2]\n\t"\
        "pop {r0, r1}\n\t"\
        ::[op]"I"(opc), [rn]"I"(crn), [rm]"I"(crm), [op2]"I"(opc2):\
    )

除了“#”標記外,這似乎做得更好。 (c%[rn]擴展為c#0)

請勿將push / pop放入嵌入式asm中。 這不僅意味着您在asm中編寫的垃圾郵件超出了您應有的水平; 由於有效地址可能是相對於堆棧指針的,因此它也排除了使用"m"類型的輸入/輸出約束。 而是使用類似:

asm volatile ("mrc p15, opc, %0, crn, crm, opc2" : "=r"(cp_reg_val));

清理了一下:

#define READ_CP15(retvar, opc, crn, crm, opc2) \
    asm volatile (\
        "mrc p15, %c[op], %[reg], c%c[rn], c%c[rm], %c[op2]\n\t"\
        :[reg] "=r" (retvar)\
        :[op]"I"(opc), [rn]"I"(crn), [rm]"I"(crm), [op2]"I"(opc2):\
    )

這些opc,crn,crm和opc2必須存在。 它們是常數。 輸出程序集是:

@ 252 "../instr_comm.c" 1
    mrc p15, 0, r0, c0, c1, 1

麥克默菲再次中風。 我花了一些時間搞清楚,但現在,我派我發現了“%”和“[名]”之間的“C”做它的問題 - 失去了“#”。

這有效:

#define READ_CP15(opc, crn, crm, opc2) \
    asm volatile (\
        "push {r0, r1}\n\t"\
        "mrc p15, %c[op], r0, c%c[rn], c%c[rm], %c[op2]\n\t"\
        "ldr r1, =cp_reg_val\n\t"\
        "str r0, [r1]\n\t"\
        "pop {r0, r1}\n\t"\
        ::[op]"I"(opc), [rn]"I"(crn), [rm]"I"(crm), [op2]"I"(opc2):\
    )

從(臨時).s文件中檢查。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM