错误:在'command'之前预期的字符串文字/重用asm volatile

时间:2017-12-17 14:46:20

标签: c++

我试图运行以下代码,写入端口。

void write(uint8_t size, uint8_t data, uint16_t port_number){
    char command[] = "out_ %0, %1";
    command[3] = size; //outb, outw or outl
    __asm__ volatile(command: : "a"(data), "Nd"(port_number) );
}

我得到了以下错误信息:

test.cpp:32:22: error: expected string-literal before ‘command’
 __asm__ volatile(command : : "a"(data), "Nd"(port_number) );

如果我尝试运行此行:

__asm__ volatile("outb %0, %1": : "a"(data), "Nd"(port_number) );

它编译没有问题。

现在,我知道我可以通过创建3个版本的写入函数来解决这个问题,每个版本的“out”都有一个版本,但有没有更好的方法来解决这个问题,而无需复制粘贴代码?

1 个答案:

答案 0 :(得分:1)

__asm__ volatile()的第一个参数AsmTemplate必须是字符串文字。

对于每个输出大小,您只需要使用相应的文字调用该函数。您可以使用if-else或switch-case在这里使用分支:

void write(uint8_t size, uint8_t data, uint16_t port_number){
    char command[] = "out_ %0, %1";
    command[3] = size; //outb, outw or out
    switch(size) {
        case 'b': __asm__ volatile("outb %0, %1": :"a"(data), "Nd"(port_number) ); break;
        case 'w' : __asm__ volatile("outw %0, %1": :"a"(data), "Nd"(port_number) ); break;
        case 'l' : __asm__ volatile("outl %0, %1": :"a"(data), "Nd"(port_number) ); break;
    } 
}

添加案例以涵盖每个可能的“大小”值。

您可以使用大小作为参数的#define来缩短每一行