如何在asm自定义指令中传递一个整数作为输入参数?

时间:2015-11-01 04:33:43

标签: assembly inline-assembly riscv

我正在尝试为自己的自定义指令运行汇编代码。

代码如下

#include <assert.h>
#include <stdio.h>
#include <stdint.h>


int main() {
  uint64_t x = 123, y = 456, z = 0, a=22;
  int i;

for(i=0;i<4;i++)
{
  asm volatile ("custom0 x0, %0, %[i], 0" : : "r"(i),[i]"r"(i));
  printf("The value of i is:- %d \n",i);
  asm volatile ("custom0 %0, x0, %[i], 1" : "=r"(z) :[i]"r"(i));
  printf("The value of z %d is:- %d \n",i,z);
}

}

所以基本上如上所示的custom0指令的工作方式如下所示。

//             opcode
//             |               address
//             |               |
//             |               |       
asm volatile ("custom0 x0, %0, 1, 0" : : "r"(i));//for moving i to address 1
asm volatile ("custom0 %0, x0, 1, 1" : "=r"(z));//for moving contents of address 1 to z.

该指令可以很好地独立运行,但是当我尝试参数化地址字段并在for循环中运行时,数据不会移动到该地址。

上述程序的输出是

The value of i is:- 0 
The value of z 0 is:- 0 
The value of i is:- 1 
The value of z 1 is:- 0 
The value of i is:- 2 
The value of z 2 is:- 0 
The value of i is:- 3 
The value of z 3 is:- 0 

正如您所看到的,i的值是正确的,但z的值始终为零。

正在使用的指令集是RISCV ISA: - http://riscv.org/download.html#tab_spec_user_isa

1 个答案:

答案 0 :(得分:1)

asm volatile ("custom0 x0, %0, %[i], 0" : : "r"(i),[i]"r"(i));

据我所知,@custom0指令(https://github.com/riscv/riscv-opcodes/blob/master/opcodes-custom)只获得2个寄存器作为第一个和第二个参数;第三个论点是&#34; imm12&#34; =立即。因此,有一种方法可以将汇编器编码为x0寄存器和%0(将是寄存器),但是imm字段应该具有&#34; i&#34; (立即)约束,而不是&#34; r&#34; (注册) - 检查关于约束的gcc doc:https://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Simple-Constraints.html#Simple-Constraints

立即字段应由汇编程序编码到命令中,它是命令二进制编码的一部分。您没有任何合法的变体来在程序的二进制代码中编码运行时变量,因此您不能将int i作为"i" asm参数传递。 "i"参数接受仅编译时常量

您可以将代码重写为4个asm语句,而不使用&#34; i&#34;和恒定值

asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(0));
asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(1));
asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(2));
asm volatile ("custom0 x0, %0, %1, 0" : : "r"(i), "i"(3));