C 表达式中的汇编指令
asm 为 gcc 中的关键字asm 表达式为在 C代码中嵌套汇编指令该表达式只是单纯的替换出汇编代码并不对汇编代码的含义进行解析。asm 表达式有两种形式第二种asm-qualifiers包含了goto语句。第一种形式为常见的用法AssemblerTemplate 和 OutputOperands 必须存在, 其中 Clobbers 存在需要 InputOperands 也出现。12345678910asm asm-qualifiers ( AssemblerTemplate: OutputOperands[ : InputOperands[ : Clobbers ] ])asm asm-qualifiers ( AssemblerTemplate:: InputOperands: Clobbers: GotoLabels)Qualifiers 的类型volatile, 避免编译器的优化inline, 内敛限定符最小的体积goto, 包含跳转指令参数AssemblerTemplate- 汇编指令模板是包含汇编器指令的文字字符串编辑器替换引用输入编译器不会解析该指令的含义。OutputOperands- 由 AssemblerTemplate 中的指令修改的C变量的逗号分隔列表允许使用空列表。InputOperands- 由 AssemblerTemplate 中的指令读取的C变量的逗号分隔列表允许使用空列表。Clobbers- 用逗号分隔的寄存器列表或由 AssemblerTemplate 修改的值不能出现在 OutputOperands 和 InputOperands 中被提及允许使用空列表。GotoLabels- 当使用asm的goto形式时此部分包含 AssemblerTemplate 中的代码可能跳转到的所有C标签的列表。AssemblerTemplate汇编指令由一个字符串给出多条汇编指令结合在一起使用的时候中间以\r\t隔开如12345678asm(inc %0\n\tinc %0 : r(res) : 0(res));/APP# 11 asm.c 1inc %raxinc %rax# 0 2/NO_APPs需要转义的字符%,,{,},|故在ATT汇编中对寄存器进行操作的需要双 %%, 如inc %%rax.OutputOperands操作数之间用逗号分隔。 每个操作数具有以下格式1[ [asmSymbolicName] ] constraint (cvariablename)asmSymbolicName- 为操作数指定名称格式为%[name]c // res num asm(movq %[num], %[res] : [res] r(res) : [num] m(num));- 如果未指定名称使用数字, 从 output 域开始第一个参数为 %0, 一次类推, 这里的 res 为 %0, num 为 %1c // res num asm(movq %1, %0 : r(res) : m(num));constraint- 一个字符串常量用于指定对操作数的存储的 约束, 需要以 或 开头cvariablename- 指定一个C左值表达式来保存输出通常是一个变量名。 括号是语法的必需部分第一个参数为增加可读性使用的现在我们有代码如下12345678910111213141516171819202122232425262728293031int64_t res;int64_t num 1;asm(movq %[num], %[res] : [res] r(res) : [num] m(num));asm(movq %1, %0 : r(res) : m(num));asm(movq %1, %0 : m(res) : m(num));asm(movq %1, %0 : r(res) : r(num));// 对应的汇编代码, 只保留asm表达式中的代码# 13 asm.c 1movq -16(%rbp), %rax // asm-1# 0 2/NO_APP/APP# 15 asm.c 1movq -16(%rbp), %rax // asm-2# 0 2/NO_APP/APP# 17 asm.c 1movq -16(%rbp), -8(%rbp) // asm-3# 0 2/NO_APP/APP# 19 asm.c 1movq %rax, %rax // asm-4# 0 2/NO_APP使用名称替换和数字替换效果一样见 asm-1 和 asm-2约束的用法这里使用比较简单通用的的两种情况r为通过寄存器寻址操作m通过内存寻址操作所以看到当约束了r就对应寄存器的操作。结果保存在 res 也就是 cvariablename 中InputOperands输入操作数使C变量和表达式中的值可用于汇编代码。1[ [asmSymbolicName] ] constraint (cexpression)asmSymbolicName 和输出列表的用法完全一致constraint 约束不能使用和. 可以使用 0, 这表明在输出约束列表中从零开始的条目指定的输入必须与输出约束位于同一位置。12345678910111213int64_t res 3;int64_t num 1;asm(addq %1, %0 : g(res) : 0(num));// 输入输出位置相同movq $3, -8(%rbp)movq $1, -16(%rbp)movq -16(%rbp), %rax/APP# 32 asm.c 1addq %rax, %rax# 0 2/NO_APPcexpression 可以不为左值作为汇编表达式的输入值即可Clobbers破坏列表主要用于指示编译器生成的汇编指令。从asm表达式中看到输出操作数中列出条目的更改编译器是可以确定的但内联汇编代码可能不仅对输出进行了修改。 例如计算可能需要其他寄存器或者处理器可能会由于特定汇编程序指令而破坏寄存器的值。 为了将这些更改通知编译器在Clobber列表中列出这些会产生副作用的条目。 破坏列表条目可以是寄存器名称也可以是特殊的破坏列表项在下面列出。 每个内容列表条目都是一个字符串常量用双引号引起来并用逗号分隔。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2564934.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!