标签: inline-assembly

<linux/unistd.h> 中的 _syscallN 宏去了哪里?

过去的情况是,如果你需要直接在 Linux 中进行系统调用而不使用现有的库,你可以只包含它<linux/unistd.h>,它会定义一个类似于以下的宏:

#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
type name(type1 arg1,type2 arg2,type3 arg3) \
{ \
long __res; \
__asm__ volatile ("int $0x80" \
  : "=a" (__res) \
  : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
      "d" ((long)(arg3))); \
if (__res>=0) \
  return (type) __res; \
errno=-__res; \
return -1; \
}
Run Code Online (Sandbox Code Playgroud)

然后你可以在代码中的某个地方放置:

_syscall3(ssize_t, write, int, fd, const void *, buf, size_t, count);
Run Code Online (Sandbox Code Playgroud)

这将为您定义一个write正确执行系统调用的函数。

似乎这个系统已经被更强大的东西(我猜测每个进程都会获得的“[vsyscall]”页面)取代。

那么程序在较新的 Linux 内核上直接执行系统调用的正确方法(请具体)是什么?我意识到我应该使用 libc 并让它为我完成工作。但我们假设我有充分的理由想知道如何做到这一点:-)。

c linux kernel system-calls inline-assembly

5
推荐指数
1
解决办法
979
查看次数

如何在 ARM GCC 内联汇编中指定单个寄存器作为约束?

在 x86 内联汇编中,我可以这样写:

asm ("cpuid"
            : "=a" (_eax),
              "=b" (_ebx),
              "=c" (_ecx),
              "=d" (_edx)
            : "a" (op));
Run Code Online (Sandbox Code Playgroud)

所以在 matchin 约束中,而不是只写“=r”并让编译器选择寄存器,我可以说我想使用哪个特定的寄存器(=a 例如使用 %eax)

我怎样才能为 ARM 程序集做到这一点?ARM GCC 汇编手册http://www.ethernut.de/en/documents/arm-inline-asm.html指出,例如,我可以将约束“r”用于通用寄存器 R0-R15“w”之一" 对于 VFP 浮点寄存器 S0-S31 之一

但是我怎样才能将一个操作数限制在例如 s1 呢?或特定的通用寄存器?

gcc arm inline-assembly

5
推荐指数
1
解决办法
3561
查看次数

SPARC的GCC内联汇编:如何处理整数双字对?

据我所知,在SPARC中,32位整数存储在单个寄存器中,64位整数存储在相邻寄存器对中,偶数寄存器包含高32位,奇数寄存器包含低32位.

我需要编写一些专门的SPARC内联汇编宏(内联汇编函数也可以)处理64位整数双字对,我无法弄清楚如何一般地引用(使用GCC扩展内联汇编)到我的内联装配中两半的一对.虽然我的汇编宏比下面显示的MULTIPLY()宏稍微复杂一些,但乘法示例(如果有效)将演示如何处理64位双字对的两半.谁能告诉我如何修复我的MULTIPLY()宏?

万一重要,我正在......

bash-2.03 $ uname -a
SunOS [...] 5.8 Generic_117350-39 sun4u sparc SUNW,Ultra-80

这是我的简单示例程序(在C中):

#include <stdio.h>
//#include <stdint.h>
#define uint32 unsigned long int
#define uint64 unsigned long long int


#define MULTIPLY(r, a, b)  /* (r = a * b) */   \
   asm("umul %1, %2, %0;"  /* unsigned mul */  \
       : /* regs out */  "=h"(r)               \
       : /* regs in  */  "r"(a),   "r"(b));
#if 0
       : /* clobbers */  "%y" );
#endif


int main(int argc, char** argv)
{ …
Run Code Online (Sandbox Code Playgroud)

c c++ gcc sparc inline-assembly

5
推荐指数
1
解决办法
2215
查看次数

如何访问 C 变量以进行内联汇编操作?

鉴于此代码:

#include <stdio.h>

int main(int argc, char **argv)
{
    int x = 1;
    printf("Hello x = %d\n", x);
}
Run Code Online (Sandbox Code Playgroud)

我想在内联汇编中访问和操作变量 x 。理想情况下,我想使用内联汇编更改其值。GNU 汇编器,并使用 AT&T 语法。

c assembly gcc inline-assembly

5
推荐指数
1
解决办法
4913
查看次数

如何读取寄存器:RAX、RBX、RCX、RDX、RSP。C 或 C++ 中的 RBP、RSI、RDI?

假设我想从双核 x64 CPU 上的这些寄存器(以及所有这些)中读取值。我怎样才能做到这一点?我可以简单地写一些类似的东西:

uint64_t rax = 0, rbx = 0;
__asm__ __volatile__ (
    /* read value from rbx into rbx */
    "movq %%rdx, %0;\n"
    /* read value from rax into rax*/
    "movq %%rax, %1;\n"
    /* output args */
    : "=r" (rbx), "=r" (rax)
    : /* no input */
    /* clear both rdx and rax */
    : "%rdx", "%rax"
);
Run Code Online (Sandbox Code Playgroud)

然后只是打印出来raxrbx?干杯

c c++ inline-assembly

5
推荐指数
1
解决办法
5346
查看次数

Common Lisp 中的汇编生成宏

我有兴趣了解程序员在纯 Common Lisp 中的底层水平如何(或者,如果做不到这一点,则在特定于实现的扩展中)。谷歌还没有给我找到太多这方面的信息,所以我想听听专家们的说法。这篇文章提到了 SBCL 的一个功能来定义作者所说的“虚拟操作符”,但是搜索“common lisp 虚拟操作符”并没有得到太多结果。作者还提到找到相关文档有多么困难。其他实现是否存在类似的系统,标准中是否有任何基础(尽管考虑到这样的功能主要用于编写 ISA 特定的代码,但对于它的用户来说,可移植性不应该是真正的优先事项) ,在哪里可以找到此类功能的文档?

如果能找到一种方法将“可编程编程语言”概念扩展到低级代码(特别是对于效率非常重要且其他用 C 或汇编语言编写的库可能不可用的领域),那就太好了。

macros common-lisp inline-assembly

5
推荐指数
1
解决办法
1663
查看次数

如何设置 gcc 以永久使用 intel 语法?

我有以下代码,可以用 gcc 命令很好地编译gcc ./example.c。程序本身调用函数“add_two”,它只是将两个整数相加。要在扩展汇编指令中使用 intel 语法,我需要首先切换到 intel,然后再切换回 AT&T。根据 gcc 文档,可以使用gcc -masm=intel ./exmaple.

每当我尝试使用 switch 编译它时,-masm=intel它都不会编译,我不明白为什么?我已经尝试删除该指令,.intel_syntax但它仍然无法编译。

#include <stdio.h>

int add_two(int, int);

int main(){
     int src = 3;
     int dst = 5;
     printf("summe = %d \n", add_two(src, dst));
     return 0;
}

int add_two(int src, int dst){

    int sum;

    asm (
        ".intel_syntax;"  //switch to intel syntax
        "mov %0, %1;"
        "add %0, %2;"

        ".att_syntax;"  //switch to at&t syntax
        : "=r" (sum) //output
        : "r" (src), "r" …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gcc inline-assembly intel-syntax

5
推荐指数
1
解决办法
4480
查看次数

内联汇编器的 Stringify 模板类型

我正在寻找一种通过模板函数自动执行 gcc 内联汇编调用的方法。
例如,我有以下虚拟函数将值存储到指针中。现在我专门针对不同类型的模板函数。每当代码发生变化时,我都需要针对每个专业化进行更改。

template <typename T>
void store_ptr(T *location, T value);

template <>
void store_ptr<char>(char *location, char value) {
  __asm__ __volatile__(
      "strb %1, [%0]\n\t"
      : "+r" (location)
      : "r" (value)
      : "memory"
  );
}


template <>
void store_ptr<short>(short *location, short value) {
  __asm__ __volatile__(
      "strh %1, [%0]\n\t"
      : "+r" (location)
      : "r" (value)
      : "memory"
  );
}
Run Code Online (Sandbox Code Playgroud)

如果模板可以根据模板类型对指令附录(“b”、“h”...)进行字符串化,那就太好了。

template <typename T>
void store_ptr<T>(T *location, T value) {
  __asm__ __volatile__(
     "str" stringify_template_type(T) " %1, [%0]\n\t"
     : "+r" (location)
     : "r" …
Run Code Online (Sandbox Code Playgroud)

c++ templates inline-assembly c++11

5
推荐指数
1
解决办法
416
查看次数

如何读取Intel处理器的PMC(性能监控计数器)?

我正在尝试使用 RDMSR 和 WRMSR 指令读取 PMC(性能监控计数器)。

\n\n

在我的具有 Intel i7 6700 CPU (Skylake) 的 Linux 桌面上,我编写了一个简单的驱动程序代码:

\n\n
static int my_init(void)\n{\n    unsigned int msr;\n    u64 low, high;\n\n    msr = 0x187;\n    low = 0x412e;\n    high = 0x0;\n\n    asm volatile("1: wrmsr\\n"\n            "2:\\n"\n            : : "c" (msr), "a"(low), "d" (high) : "memory");\n\n    msr = 0xC2;\n    asm volatile("1: rdmsr\\n"\n            "2:\\n"\n            : "=a" (low), "=d" (high) : "c" (msr)); \n\n    printk("val: %lu\\n", (low) | ((high) << 32));\n\n    return  0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

参考Intel手册(18.2 ARCHITECTURAL PERFORMANCE MONITORING in Intel\xc2\xae …

x86 intel performancecounter inline-assembly intel-pmu

5
推荐指数
1
解决办法
4508
查看次数

使用 goto 扩展 asm,包括 gcc 文档中的一个示例,无法编译

某些使用goto限定符的扩展汇编语句无法使用 GCC 10.1.0 进行编译。具体来说,

int foo(int count)
{
  asm goto ("dec %0; jb %l[stop]"
            : "+r" (count)
            :
            :
            : stop);
  return count;
stop:
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

(这是GCC 扩展 asm 文档中的一个示例)无法使用消息编译expected ‘:’ before string constant。删除"+r" (count)dec %0允许它成功编译,但无论我在何时尝试在与 goto 标签相同的 asm 语句中提供输出操作数时,它都会以同样的方式出错。

c gcc goto inline-assembly

5
推荐指数
2
解决办法
220
查看次数