标签: inline-assembly

这两种形式的内联汇编程序在C中有什么区别?

背景:我的任务是为Unitech HT630编写一个数据收集程序,它运行一个专有的DOS操作系统,可以运行为16位MS DOS编译的可执行文件,尽管有一些限制.我正在使用Digital Mars C/C++编译器,它似乎运行得很好.

对于某些我可以使用标准C库的东西,但是在单元的屏幕上绘制等其他东西需要汇编代码.设备文档中给出的汇编示例与我在C/C++中使用内联汇编代码的方式不同.作为参考,BYTE在以下示例中是类型unsigned char.

给出了示例代码的示例:

#include <dos.h>

/* Set the state of a pixel */
void LCD_setpixel(BYTE x, BYTE y, BYTE status) {
  if(status > 1 || x > 63 || y > 127) {
    /* out of range, return */
    return;
  }
  /* good data, set the pixel */
  union REGS regs;
  regs.h.ah = 0x41;
  regs.h.al = status;
  regs.h.dh = x;
  regs.h.dl = y;
  int86(0x10, &regs, &regs);
}
Run Code Online (Sandbox Code Playgroud)

我如何被教导使用内联汇编:

/* …
Run Code Online (Sandbox Code Playgroud)

c assembly dos inline-assembly

7
推荐指数
1
解决办法
1629
查看次数

C/C++中的简单"Hello World"内联汇编语言程序

我用devcpp和borland c编译器....

asm {
    mov ax,4       // (I/O Func.)
    mov bx,1       // (Output func)  
    mov cx,&name   // (address of the string)
    mov dx,6       // (length of the string)
    int 0x21       // system call
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码片段中,我想在汇编语言的帮助下打印一个字符串...但是如何将字符串的地址放在寄存器cx ....

代码中有什么问题???

c x86 assembly inline-assembly

7
推荐指数
1
解决办法
8721
查看次数

与SSE进行128位哈希比较


在我目前的项目中,我必须比较128位值(实际上是md5哈希),我认为可以通过使用SSE指令来加速比较.我的问题是我无法找到关于SSE指令的好文档; 我正在寻找一个128位整数比较指令,让我知道一个散列是大于,小于或等于另一个.这样的指令是否存在?

PS:目标计算机是带有SSE2指令的x86_64服务器; 我也对同一工作的NEON指令感兴趣.

c assembly sse inline-assembly neon

7
推荐指数
2
解决办法
3408
查看次数

x64的"自定义内在"功能可以代替内联汇编吗?

我目前正在尝试为我的图书馆创建高度优化,可重复使用的功能.例如,我通过以下方式编写函数"is power of 2":

template<class IntType>  
inline bool is_power_of_two( const IntType x )
{
    return (x != 0) && ((x & (x - 1)) == 0);
}
Run Code Online (Sandbox Code Playgroud)

这是一个可移植,低维护的实现,作为内联C++模板.此代码由VC++ 2008编译为具有分支的以下代码:

is_power_of_two PROC
    test    rcx, rcx
    je  SHORT $LN3@is_power_o
    lea rax, QWORD PTR [rcx-1]
    test    rax, rcx
    jne SHORT $LN3@is_power_o
    mov al, 1
    ret 0
$LN3@is_power_o:
    xor al, al
    ret 0
is_power_of_two ENDP
Run Code Online (Sandbox Code Playgroud)

我从这里找到了实现:"bit twiddler",它将在x64的程序集中编码,如下所示:

is_power_of_two_fast PROC
    test rcx, rcx
    je  SHORT NotAPowerOfTwo
    lea rax, [rcx-1]
    and rax, …
Run Code Online (Sandbox Code Playgroud)

c++ 64-bit assembly inline-assembly intrinsics

7
推荐指数
1
解决办法
2169
查看次数

Metro Windows 8 C++应用程序可以包含内联汇编程序吗?

Metro Windows 8应用程序可以包含内联汇编程序吗?也是Metro C++ Native,或托管,或者你可以像C++/CLI一样混合它们吗?

c++ inline-assembly microsoft-metro windows-8 windows-runtime

7
推荐指数
1
解决办法
1841
查看次数

如何在x86汇编编程中表示十六进制值如FFFFFFBB?

我正在学习x86内联汇编编程.

我想写mov ecx, FFFFFFBB,但编译器没有认识到它.这样的十六进制数应该如何用内联汇编代码编写?

x86 assembly inline-assembly

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

gcc内在vs内联汇编:哪个更好?

如果我想向程序员公开一个特定于机器的指令,我有两种方法可以这样做:

  1. 定义一个新的内置/内在
  2. 暴露与内联汇编asm()相同[由于它是一个算术类型的指令,我相信不需要asm volatile()]

我已经读过内置函数允许编译器处理类型检查,寄存器分配和"其他优化"等.但是即使在asm()的情况下,编译器也需要这样做,对吧?那么对于单个指令使用asm()内在的性能优势究竟是什么呢?

如果涉及多个机器指令,方程式如何变化?

支持内在的"可移植性"论证是可以理解的,但我很想知道其中一个的性能优势(如果有的话).

c compiler-construction assembly gcc inline-assembly

7
推荐指数
1
解决办法
1464
查看次数

在函数中更改数组值 - 内联汇编

所以我在一段时间后自学了x86程序集,只是在C++中使用内联汇编.

所以我想做的是在函数参数,传入数组,索引(unsigned int)和数字.使用程序集,它会将数组的内存位置中的值更改为传入的值.所以代码看起来像这样.

inline void Set( int pArray[], unsigned int pIndex, int pNum ) {
    __asm {
        mov ebx, pIndex
        mov eax, 4
        mul ebx
        mov ebx, pNum

        lea edi, pArray
        mov [ edi + eax ], ebx
    }
}

int main() {
    int myArray[ 5 ] = { 1, 2, 3, 4, 5 };
    Set( myArray, 2, 7 );
    std::cout << myArray[ 2 ] << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

所以代码应该加载数组地址的开头,获取索引并将其乘以4,以便内存位置移动那么多字节,然后将其更改为传入的值.但是,当我这样做时,值保持不变.这是为什么?出了什么问题?

c++ arrays x86 assembly inline-assembly

7
推荐指数
1
解决办法
976
查看次数

输出“i8”时,从内联汇编中删除多余的“andi ..., 0xff”指令

我有以下使用内联汇编的函数,目标mipsel-unknown-linux-gnu

#![feature(asm)]

#[no_mangle]
pub unsafe extern "C" fn f(ptr: u32) {
    let value: i8;
    asm!(
        "lb $v0, ($a0)",
        in("$4") ptr,
        out("$2") value,
    );
    asm!(
        "sb $v0, ($a0)",
        in("$4") ptr,
        in("$2") value,
    );
}
Run Code Online (Sandbox Code Playgroud)

我预计这会编译成以下内容:

lb $v0, ($a0)
sb $v0, ($a0)
jr $ra
nop
Run Code Online (Sandbox Code Playgroud)

注意:在此示例中,编译器可能会在跳转后将存储指令重新排序以使用延迟槽,但在我的实际用例中,我通过块返回asm,因此不必担心。鉴于此,我完全预料到了上面的装配。

相反,我得到的是:

00000000 <f>:
   0:   80820000        lb      v0,0(a0)
   4:   304200ff        andi    v0,v0,0xff
   8:   a0820000        sb      v0,0(a0)
   c:   03e00008        jr      ra
  10:   00000000        nop
Run Code Online (Sandbox Code Playgroud)

编译器似乎不相信我的输出是 ani8andi $v0, 0xff在那里插入了一条指令。

我需要准确地生成上面指定的程序集,因此我想删除该andi …

mips inline-assembly rust

7
推荐指数
0
解决办法
189
查看次数

如何使用 gcc 风格的内联汇编打印寄存器号?

受到最近一个问题的启发。

gcc 式内联汇编的一种用例是对编译器和汇编器都不知道的指令进行编码。例如,我给出了如何在太旧而无法支持的工具链上使用指令的示例:rdrand

/* "rdrand %%rax ; setc %b1" */
asm volatile (".byte 0x48, 0x0f, 0xc7, 0xf0; setc %b1"
    : "=a"(result), "=qm"(success) :: "cc");
Run Code Online (Sandbox Code Playgroud)

不幸的是,对指令进行硬编码意味着您还需要对其使用的寄存器进行硬编码,从而大大减少了编译器执行寄存器分配的自由度。

在某些架构上(例如带有.insn指令的 RISC-V),汇编器提供了一种系统地构建原始指令的方法,但这似乎是例外。

一个简单的解决方案是有一种方法来获取寄存器的未修饰编号,以将其手动编码到指令中。例如,假设X存在模板修饰符来打印所选寄存器的编号。那么,上面的例子可以变得更加灵活:

/* "rdrand %0 ; setc %b1" */
asm volatile (".byte 0x48 | (%X0 >> 3), 0x0f, 0xc7, 0xf0 | (%X0 & 7); setc %b1"
    : "=r"(result), "=qm"(success) :: "cc");
Run Code Online (Sandbox Code Playgroud)

同样,如果有一种方法可以让 gcc 打印12而不是v12ARM64 上的 SIMD 寄存器 12,则可以执行如下操作:

float32x4_t add3(float32x4_t a, float32x4_t b) …
Run Code Online (Sandbox Code Playgroud)

assembly gcc clang inline-assembly arm64

7
推荐指数
1
解决办法
524
查看次数