汇编程序模板,asmSymbolicName和"错误:期望的字符串字面" [英] Assembler templates, asmSymbolicName and "error: expected string-literal"

查看:656
本文介绍了汇编程序模板,asmSymbolicName和"错误:期望的字符串字面"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用GCC的扩展ASM像微软的汇编。根据微软的MASM,我们可以做到以下几点,其中 __ FUNC 是一个C变量:

  MOV EAX,__FUNC

根据扩展ASM - 汇编指令用C防爆pression操作数,第6.44.3.1的输入操作数的:


  

操作数之间用逗号隔开。每个操作数的格式为:

  [asmSymbolicName]约束(CEX pression)


  
  

asmSymbolicName


  
  

    指定操作数的符号名。在方括号括起来的汇编程序模板引用名称(即'%[超值]')。名称的范围是包含定义汇编语句。任何有效的C变量名是可以接受的,包括在周围code已定义的名称...


当我尝试在code使用它:

  unsigned int类型FUNC = 1;
...__asm​​__ __volatile__(
  MOVL%[__ FUNC],EAX %%
  ...  :
  :__FUNC(FUNC)
);

这结果是:

  cpu.cpp:148:5:错误:期望的字符串字面'__FUNC前
 :__FUNC(FUNC)
   ^
cpu.cpp:148:5:错误:预期'(''__FUNC前
cpu.cpp:148:17:错误:'__FUNC在此范围未声明
...

我可以告诉大家,我现在用的是最好的 __ FUNC 根据手册及其 asmSymbolicName 的说明。但很明显,我不是因为有一个错误。

我在做什么错了?


我也试过以下,因为手册告诉我可以在周围code使用的变量名,但它没有工作,要么:

 MOVL%[FUNC],EAX %%
...:
:FUNC(FUNC)

 MOVL%[FUNC],EAX %%
...:
:FUNC(FUNC)
...


解决方案

这是正确的:


  

操作数之间用逗号隔开。每个操作数的格式为:

  [asmSymbolicName]约束(CEX pression)


[asmSymbolicName] 办法 asmSymbolicName 简直是用方括号包围 [] (外面的括号说,这是一个可选参数)。你可能已经持续了这一点:

  uint32_t的FUNC = 1;
uint32_t的结果;__asm​​__ __volatile__(
    MOVL%[FUNC],%[结果]
    :[结果]= A(结果)
    :[FUNC]G(FUNC)
);

这需要FUNC 的输入参数使其可作为汇编模板中名为 FUNC 符号名称。输出参数是 EAX (写)与结果的符号名和 EAX 将被存储在完成结果当C变量。我选择了G,因为任何直接的价值,内存地址或寄存器将适用于在 MOVL 源。你可以传递一个直接的价值,而不是一个C变量:

 :[FUNC]G(42)

I'm trying to use GCC's extended ASM like Microsoft's assembler. Under Microsoft's MASM, we can do the following, where __FUNC is a C variable:

mov eax, __FUNC

According to Extended Asm - Assembler Instructions with C Expression Operands, § 6.44.3.1 Input Operands:

Operands are separated by commas. Each operand has this format:

 [ [asmSymbolicName] ] constraint (cexpression)

asmSymbolicName

     Specifies a symbolic name for the operand. Reference the name in the assembler template by enclosing it in square brackets (i.e. ‘%[Value]’). The scope of the name is the asm statement that contains the definition. Any valid C variable name is acceptable, including names already defined in the surrounding code...

When I try and use it in code:

unsigned int func = 1;
...

__asm__ __volatile__ (
  "movl %[__FUNC], %%eax"
  ...

  :
  : __FUNC "" (func)
);

It results in:

cpu.cpp:148:5: error: expected string-literal before ‘__FUNC’
 : __FUNC "" (func)
   ^
cpu.cpp:148:5: error: expected ‘(’ before ‘__FUNC’
cpu.cpp:148:17: error: ‘__FUNC’ was not declared in this scope
...

The best I can tell, I am using __FUNC according to the manual and its description of asmSymbolicName. But obviously I am not since there's an error.

What am I doing wrong?


I also tried the following because the manual told me I could use variable names in surrounding code, but it did not work either:

"movl %[func], %%eax"
...

:
: func "" (func)

And:

"movl %[func], %%eax"
...

:
: func (func)
...

解决方案

This is correct:

Operands are separated by commas. Each operand has this format:

[  [asmSymbolicName]  ] constraint (cexpression)

However [asmSymbolicName] means asmSymbolicName is literally surrounded by square brackets [ and ] (The outside brackets say that it is an optional parameter). You might have been going for this:

uint32_t func = 1;
uint32_t result;

__asm__ __volatile__ (
    "movl %[func], %[result]"
    : [result]"=a"(result)
    : [func]"g"(func)
);

This takes an input parameter of func makes it available as a symbolic name called func within the assembler template. Output parameter is eax (writable) with a symbolic name of result and eax will be stored in the C variable result when finished. I chose "g" since any immediate value, memory address, or register would be appropriate for the source in movl . You could pass an immediate value rather than a "C" variable with:

: [func]"g"(42)

这篇关于汇编程序模板,asmSymbolicName和"错误:期望的字符串字面"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆