我正在尝试为自己的自定义指令运行汇编代码。
代码如下
#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
答案 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));