如何在C代碼中使用內聯彙編之asm操作數的約束

asm操作數的約束
約束
可以說明操作數是否在寄存器中
可以說明寄存器的類型
可以說明操作數是否可以作爲內存引用
可以說明操作數地址的種類
可以說明操作數是否是立即數,
可以說明操作數可能具有哪些值。
也可以說明要求兩個操作數匹配。
內聯asm的操作數中不允許有副作用
如果使用了’ < ‘或’ > '約束,就有可能有副作用,因爲不能保證副作用在可以更新尋址寄存器的指令中只發生一次。

• Simple Constraints: Basic use of constraints.
• Multi-Alternative: When an insn has two alternative constraint-patterns.
• Modifiers: More precise control over effects of constraints.
• Machine Constraints: Special constraints for some particular machines.

簡單的約束
https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Simple-Constraints.html#Simple-Constraints
空格
空白字符將被忽略
‘m’
內存操作數是允許的,通常機器支持任何類型的地址。
注意,用於通用內存約束的字母可以使用TARGET_MEM_CONSTRAINT宏的後端重新定義
‘o’
‘V’
‘<’
‘>’
‘r’
如果寄存器操作數位於通用寄存器中,則允許它。
‘i’
‘n’
‘I’,‘J’,‘k’,… ‘P’
‘E’
‘F’
‘G’,‘H’
‘s’
‘g’
‘X’
‘0’,‘1’,‘2’,… ‘9’
‘p’
其他字母

多個可選約束
https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Multi-Alternative.html#Multi-Alternative
有時,一條指令有多個可選操作數集。例如,在68000上,邏輯或指令可以將寄存器或一個立即值組合到內存中,也可以將任何一種操作數組合到寄存器中;但是它不能將一個內存位置合併到另一個內存位置。
這些約束表示爲多個備選項。一種替代方法可以用每個操作數的一系列字母來描述。
操作數的總體約束由第一個備選項的操作數的字母(逗號)和第二個備選項的操作數的字母(逗號)構成,以此類推,直到最後一個備選項。一條指令的所有操作數必須具有相同數量的替代項。

約束的修飾符字符
https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Modifiers.html#Modifiers
‘=’
表示此操作數是由這條指令寫入的:以前的值將被丟棄,並由新數據替換。
‘+’
表示該操作數由指令讀取和寫入。
當編譯器修復操作數以滿足約束時,它需要知道哪些操作數由指令讀取,哪些操作數由指令編寫
’ = ‘標識僅寫入的操作數;’ + ‘標識一個既可讀又可寫的操作數;
如果在約束中指定’ = ‘或’ + ‘,則將其放在約束字符串的第一個字符中。
‘&’
表示(在特定的替代方法中)這個操作數是一個earlyclobber操作數,它是在使用輸入操作數完成指令之前編寫的。
在此之前,這個操作數不能存在於指令讀取的寄存器中,也不能作爲任何內存地址的一部分。
‘%’
這意味着編譯器可以交換兩個操作數,如果這是使所有操作數都符合約束的最便宜的方法。’ % ‘適用於所有替代,並且必須作爲約束中的第一個字符出現。只有只讀操作數可以使用’ % '。

特定於機器的約束

https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Machine-Constraints.html#Machine-Constraints

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章