标签: inline-assembly

什么是简单的C函数的例子,它在内联汇编中实现得更快?

我很难用内联汇编来击败我的编译器.

什么是一个好的,非人为的函数示例,编译器很难制作真正,快速和简单的函数?但是使用内联汇编制作相对简单.

assembly inline-assembly

10
推荐指数
5
解决办法
2073
查看次数

Linux汇编程序错误"'asm'中不可能的约束"

我在Linux下开始使用汇编程序.我已将以下代码保存为testasm.c
并使用以下代码进行编译:gcc testasm.c -otestasm
编译器回复:"'asm'中的不可能约束".

#include <stdio.h>
int main(void)
{
    int foo=10,bar=15;

    __asm__ __volatile__ ("addl %%ebx,%%eax"
        : "=eax"(foo) 
        : "eax"(foo), "ebx"(bar) 
        : "eax" 
    );

    printf("foo = %d", foo);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?(我从这里复制了这个例子.)

Debian Lenny,内核2.6.26-2-amd64
gcc版本4.3.2(Debian 4.3.2-1.1)

解决方案:
查看已接受的答案 - 似乎不再支持'modified'子句.

linux assembly gcc inline-assembly

10
推荐指数
2
解决办法
3万
查看次数

在Dev-C++中定义GCC内联汇编中的字节(.在Windows上的AT&T语法中的ascii)

下面的代码只是在屏幕上显示一个消息框.
地址是硬编码的,以方便:

int main ()
{
    asm("xorl %eax, %eax        \n"
        "xorl %ebx, %ebx        \n"
        "xorl %ecx, %ecx        \n"
        "xorl %edx, %edx        \n"
        "pushl %ecx             \n" //$0x0
        "pushl $0x20206c6c      \n" //"  ll"
        "pushl $0x642e3233      \n" //"d.23"
        "pushl $0x72657375      \n" //"resu"
        "movl %esp, %ecx        \n" //store "user32.dll" address in %ecx
        "movl $0x7c801d7b, %ebx \n" //store address of LoadLibraryA in %ebx
        "pushl %ecx             \n"
        "call *%ebx             \n"
        "movl $0xef30675e, %ecx \n"
        "addl $0x11111111, %ecx \n"
        "pushl %ecx             \n"
        "pushl $0x42656761      \n"
        "pushl $0x7373654d …
Run Code Online (Sandbox Code Playgroud)

assembly gcc inline-assembly dev-c++ att

10
推荐指数
1
解决办法
4863
查看次数

如何从程序中访问控制寄存器cr0,cr2,cr3?获得分段错误

我编写了一个程序,试图读取和写入控制寄存器.

程序编译很好,但是当即将执行内联汇编时,它会产生分段错误.

码:

void instructions(int val)
{
    int i;
    int value;
    for(i = 0; i < val; i++)
         __asm__("mov %cr0, %eax");
}
Run Code Online (Sandbox Code Playgroud)

我使用了GDB并逐步完成了每个装配线,并且mov %cr0,%eax正在发生分段故障.

谁知道什么是错的?

x86 inline-assembly cpu-registers

10
推荐指数
1
解决办法
1万
查看次数

使用带有立即值的指令的GCC内联汇编

问题

我正在为ARM Cortex-M3处理器开发自定义操作系统.要与我的内核交互,用户线程必须生成SuperVisor Call(SVC)指令(以前称为SWI,用于SoftWare中断).ARM ARM中该指令的定义是:

在此输入图像描述

这意味着该指令需要立即参数,而不是寄存器值.

这使我很难以可读的方式构建我的界面.它需要如下代码:

asm volatile( "svc #0");
Run Code Online (Sandbox Code Playgroud)

当我更喜欢像

svc(SVC_YIELD);
Run Code Online (Sandbox Code Playgroud)

但是,我无法构造这个函数,因为SVC指令需要立即参数,当值通过寄存器传入时我无法提供.

内核:

对于后台,svc指令在内核中解码如下

#define SVC_YIELD   0
// Other SVC codes

// Called by the SVC interrupt handler (not shown)
void handleSVC(char code)
{
  switch (code) {

    case SVC_YIELD:
      svc_yield();
      break;
    // Other cases follow
Run Code Online (Sandbox Code Playgroud)

这个案例陈述正在迅速失控,但我认为没有解决这个问题.欢迎任何建议.

我试过的

带有寄存器参数的SVC

我最初考虑过

__attribute__((naked)) svc(char code)
{
    asm volatile ("scv r0"); 
}
Run Code Online (Sandbox Code Playgroud)

但是,当然,这不起作用,因为SVC需要寄存器参数.

蛮力

蛮力企图解决问题看起来像:

void svc(char code)
  switch (code) {
    case 0:
      asm volatile("svc #0");
      break;
    case 1:
      asm …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc arm inline-assembly

10
推荐指数
1
解决办法
6825
查看次数

在LLVM中调用fsincos指令比调用libc sin/cos函数要慢吗?

我正在研究用LLVM编译的语言.只是为了好玩,我想做一些微基准测试.其中一个,我在一个循环中运行了一百万个sin/cos计算.在伪代码中,它看起来像这样:

var x: Double = 0.0
for (i <- 0 to 100 000 000)
  x = sin(x)^2 + cos(x)^2
return x.toInteger
Run Code Online (Sandbox Code Playgroud)

如果我使用以下形式使用LLVM IR内联汇编来计算sin/cos:

%sc = call { double, double } asm "fsincos", "={st(1)},={st},1,~{dirflag},~{fpsr},~{flags}" (double %"res") nounwind
Run Code Online (Sandbox Code Playgroud)

这比分别使用fsin和fcos而不是fsincos更快.但是,它比我分别调用llvm.sin.f64and llvm.cos.f64intrinsics,编译调用C math lib函数要慢,至少使用我正在使用的目标设置(x86_64启用了SSE).

似乎LLVM在单/双精度FP之间插入一些转换 - 这可能是罪魁祸首.这是为什么?对不起,我是大会上的新手:

    .globl  main
    .align  16, 0x90
    .type   main,@function
main:                                   # @main
    .cfi_startproc
# BB#0:                                 # %loopEntry1
    xorps   %xmm0, %xmm0
    movl    $-1, %eax
    jmp     .LBB44_1
    .align  16, 0x90
.LBB44_2:                               # %then4
                                    #   in Loop: Header=BB44_1 Depth=1 …
Run Code Online (Sandbox Code Playgroud)

assembly llvm inline-assembly x87

10
推荐指数
1
解决办法
3740
查看次数

汇编中的GetThreadID

我阅读了FastMM4的源代码,并注意到这个有趣的功能

function GetThreadID: Cardinal;
{$ifdef 32Bit}
asm
  mov eax, FS:[$24]
end;
{$else}
begin
  Result := GetCurrentThreadID;
end;
{$endif}
Run Code Online (Sandbox Code Playgroud)

我已经测试了它,它有效,所以我的问题是任何解释为什么它有效?

delphi x86 inline-assembly fastmm

10
推荐指数
1
解决办法
772
查看次数

错误:'asm'未声明(首次使用此功能)

我在编译期间收到以下错误:

error: ‘asm’ undeclared (first use in this function)
 EXCHANGE( s, *(a) );
 ^
Run Code Online (Sandbox Code Playgroud)

在头文件中调用宏,如下所示:

EXCHANGE( s, *(a) );
Run Code Online (Sandbox Code Playgroud)

并且宏的实际定义如下:

#define EXCHANGE(R,M) asm volatile ( "xchg   %1, %0" : "+m" (M), "+r" (R) )
Run Code Online (Sandbox Code Playgroud)

宏调用和定义存在于同一个头文件中.出了什么问题?

我正在使用CMAKE来构建项目,CFLAGS如下:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-braces")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-field-initializers")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat=2")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wswitch-default")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wcast-align")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith")
#-Wno-deprecated-declarations to suppress the deprecation errors with newer version of JSON-C 
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wbad-function-cast") …
Run Code Online (Sandbox Code Playgroud)

c linux gcc inline-assembly

10
推荐指数
2
解决办法
9221
查看次数

在ARM中是否有与rdtsc等效的指令?

对于我的项目,我必须使用内联汇编指令(如rdtsc)来计算某些C/C++指令的执行时间.

以下代码似乎适用于英特尔,但不适用于ARM处理器:

{unsigned a, d;asm volatile("rdtsc" : "=a" (a), "=d" (d)); t0 = ((unsigned long)a) | (((unsigned long)d) << 32);}
//The C++ statement to measure its execution time
{unsigned a, d;asm volatile("rdtsc" : "=a" (a), "=d" (d)); t1 = ((unsigned long)a) | (((unsigned long)d) << 32);}
time = t1-t0;
Run Code Online (Sandbox Code Playgroud)

我的问题是:

如何在ARM处理器上编写类似于上面内联汇编代码(计算指令的执行经过时间)?

c c++ assembly arm inline-assembly

10
推荐指数
2
解决办法
4717
查看次数

在两个ASM GCC内联块之间传播进位

亲爱的Assembly/C++ dev,

问题是:传播两个ASM块之间的进位(或任何标志)是现实的还是完全疯狂的,即使它有效?

几年前,我为低于512位的大型算术开发了一个整数库(在编译时).我此时没有使用GMP,因为对于这种规模,GMP由于内存分配而变慢,并且模型选择二进制表示工作台.

我必须承认我创建了我的ASM(字符串块)使用BOOST_PP,它不是非常光荣(好奇的看看它vli).图书馆运作良好.

但是我注意到,此时不可能在两个ASM内联块之间传播状态寄存器的进位标志.这是合乎逻辑的,因为对于编译器在两个块之间生成的任何助记符,寄存器被复位(mov指令除外(来自我的汇编知识)).

昨天我有一个想法,传播两个ASM块之间的进位有点棘手(使用递归算法).它工作,但我认为我很幸运.

#include <iostream>
#include <array>
#include <cassert>
#include <algorithm>

//forward declaration
template<std::size_t NumBits>
struct integer;


//helper using object function, partial specialization  is forbiden on functions
template <std::size_t NumBits, std::size_t W, bool K = W == integer<NumBits>::numwords>
struct helper {
    static inline void add(integer<NumBits> &a, const integer<NumBits> &b){
        helper<NumBits, integer<NumBits>::numwords>::add(a,b);
    }
};

// first addition (call first)
template<std::size_t NumBits, std::size_t W>
struct helper<NumBits, W, 1> {
    static …
Run Code Online (Sandbox Code Playgroud)

c++ assembly inline-assembly clang++

10
推荐指数
1
解决办法
290
查看次数

标签 统计

inline-assembly ×10

assembly ×7

gcc ×4

c ×3

arm ×2

c++ ×2

linux ×2

x86 ×2

att ×1

clang++ ×1

cpu-registers ×1

delphi ×1

dev-c++ ×1

fastmm ×1

llvm ×1

x87 ×1