标签: inline-assembly

为什么在 AT&T 程序集中尝试使用“*...(%rip)”进行 RIP 相对直接跳转时,会得到一个奇怪的长操作码?

问题是我不能强迫gnu as将其解释jmpshortor near,它不断地将其解释为far

例如,以下代码会导致segfault

int main() {
  asm volatile (
//      ".intel_syntax noprefix\n\t"
//      "jmp lbl%=\n\t"
//      "lbl%=:\n\t"
      "jmp *lbl%=(%%rip)\n\t"
      "lbl%=:\n\t"
//      ".att_syntax\n\t"
      : : : );
  return 0;
}

Run Code Online (Sandbox Code Playgroud)

切换到注释的.intel_syntax变体,它工作得很好。

唯一的区别是

jmp lbl%=变成inteleb 00

尽管

jmp *lbl%=(%%rip)变成attff 25 00 00 00 00

.att_syntax如果将其解释为 ,如何强制它short jump

assembly x86-64 gnu-assembler inline-assembly att

2
推荐指数
1
解决办法
116
查看次数

GCC 优化会损坏系统调用存根

GCC 的最新版本(包括版本 12)实现了过程间分析,该分析会严重损坏 ARM/Thumb 上系统调用存根的以下(仅限 GCC)代码。

typedef struct { int sender; int arg; } message;

#define syscall(op)  asm volatile ("svc %0" :: "i"(op))

#define SYS_SEND 9

#define NOINLINE __attribute((noinline))

void NOINLINE send(int dest, int type, message *msg)
{
    syscall(SYS_SEND);
}

void send_int(int d, int t, int v)
{
    message msg;
    msg.arg = v;
    send(d, t, &msg);
}
Run Code Online (Sandbox Code Playgroud)

目的是操作系统的陷阱处理程序将send通过访问参数寄存器的保存值来找到三个参数r0——r2在陷阱的异常帧中。问题显然是优化器在查看 的主体时send认为其消息参数的字段未被使用。msg.arg因此,主体中对 的赋值send_int被删除。这是通过编译上述源代码揭示的

arm-none-eabi-gcc -mcpu=cortex-m0 -mthumb -O -g -Wall -ffreestanding -c …
Run Code Online (Sandbox Code Playgroud)

c optimization gcc arm inline-assembly

2
推荐指数
1
解决办法
124
查看次数

在 Rust 内联汇编中使用字符串常量

我正在尝试write使用 Rust 中的内联汇编来执行系统调用。基本上我正在尝试重现这个 hello world 示例。我试图传递对字符串切片的引用作为我的消息,但我收到以下错误,该错误似乎与其自身相矛盾:

cannot use value of type `*const str` for inline assembly
only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
Run Code Online (Sandbox Code Playgroud)

代码如下,但我的问题是:

  1. 有没有比 a 更合适的指针类型*const str
  2. 我仍处于组装工作的早期阶段,是否还有其他我遗漏的明显问题?
cannot use value of type `*const str` for inline assembly
only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly
Run Code Online (Sandbox Code Playgroud)

它在 MacOS v13.6、M1 芯片 (Armv8.5-a) 上运行。

assembly inline-assembly rust arm64

2
推荐指数
1
解决办法
189
查看次数

明显操作的复杂代码

有时,主要出于优化目的,非常简单的操作被实现为复杂和笨拙的代码.

一个例子是这个整数初始化函数:

void assign( int* arg )
{
    __asm__ __volatile__ ( "mov %%eax, %0" : "=m" (*arg));
}
Run Code Online (Sandbox Code Playgroud)

然后:

int a;
assign ( &a );
Run Code Online (Sandbox Code Playgroud)

但实际上我不明白为什么用这种方式写的......

你有没有看到任何有真正理由的例子?

c++ optimization inline-assembly

1
推荐指数
2
解决办法
1125
查看次数

一些内联汇编程序问题

我已经在这里问了类似的问题,但我仍然有一些错误,所以我希望你能告诉我我做错了什么.只知道我知道汇编程序,并且我在8051汇编程序中完成了几个项目,即使它不一样,也接近于x86 asm.

我在VC++ 2010 Express中试过一段代码(我试图从CPUID指令中获取信息):`

int main()
{
char a[17]; //containing array for the CPUID string
a[16] = '\0'; //null termination for the std::cout
void *b=&a[0]; 
int c=0; //predefined value which need to be loaded into eax before cpuid

_asm
{
    mov eax,c;
    cpuid;
    mov [b],eax;
    mov [b+4],ebx;
    mov [b+8],ecx;
    mov [b+12],edx;
}
std::cout<<a;
}`
Run Code Online (Sandbox Code Playgroud)

因此,为了快速总结,我尝试创建指向数组第一个元素的void指针,而不是使用间接寻址只是从寄存器移动值.但是这种方法让我"堆栈b变量是运行时错误",但我不知道为什么.

请帮忙.谢谢.这只是为了研究目的,我知道有CPUID的功能....

编辑:另外,如何在x86 VC++ 2010内联汇编程序中使用直接寻址?我的意思是8051中立即数字加载的常用语法是mov src,#numberVC++ asm,mov dest,number没有#符号.那么如何告诉编译器你想直接访问内存单元地址x?

x86 assembly inline-assembly visual-c++ cpuid

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

内联汇编错误:'asm'中的未知寄存器名称'%% ebx'

我试图创建read()包装但收到此错误:

错误:第23行'(asm')中的未知寄存器名称'%% ebx'//(粗线)

这是代码:

#include <sys/syscall.h>
typedef unsigned int size_t;
typedef signed ssize_t;

extern int errno;

int main(void) {
    int fd = 0;
    char buf[128];
    size_t count = 128;
    my_read(fd, buf, count);

    return 0;
}

int my_read(int fd, void *buf, size_t count) {
    long ret;

    asm("pushl %%ebx\n\t" // Line 23
        "movl %%esi,%%ebx\n\t"
        "int $0x80\n\t"
        "popl %%ebx"
        : "=a" (ret)/* output */
        : "0"(SYS_read), "S"((long) fd), "c"((long) buf), "d"((long) count)/* input */
        : "%%ebx"/* clobbered register */
        );
    if (ret >= …
Run Code Online (Sandbox Code Playgroud)

c inline-assembly

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

在gcc上的内联asm中使用printf函数

我想在gcc上测试内联asm capabilty.因此,我在64位的ubuntu 12.04上键入并编译以下代码,但系统在运行时会在屏幕上显示"分段错误".我不知道导致问题的原因.

#include <stdio.h>
char Format[]="Hello world %d\n";
int main()
{
    asm
    (
        "movl $3,4(%esp);"
        "movl $Format,(%esp);"
        "call printf;"
    );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

谢谢你们帮我一个程序新手.我使用Code :: blocks作为IDE来编写此代码.我曾尝试使用像%rdx这样的64位寄存器,但编译代码时Build消息的日志显示"Error:bad register name`%rdx'".我认为这意味着Code :: blocks调用的gcc是3​​2位版本,因此无法识别这些寄存器.我修改代码以保留堆栈空间

#include <stdio.h>
char Format[]="Hello world %d\n";
int main()
{
    asm
    (
        "subl $8,%esp;"         //I  don't know  $4, $8, $12, $16, $20 which is correct
                                        //but I had tried them all but results are still  ''segmentation fault."
        "movl $3,4(%esp);"
        "movl $Format,(%esp);"
        "call printf;"
        "movl %ebp,%esp;"
    );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

甚至使用-m32作为编译器选项,但它仍然显示"分段错误". …

c assembly gcc inline-assembly segmentation-fault

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

smulwb组装说明

我正在尝试理解以下代码:

inline SInt32 smul32by16(SInt32 i32, SInt16 i16)
{
    register SInt32 r;
    asm volatile("smulwb %0, %1, %2" : "=r"(r) : "r"(i32), "r"(i16));
    return r;
}
Run Code Online (Sandbox Code Playgroud)

有人知道这个汇编指令做什么吗?

更新: PS我使用目标C。我应该从汇编中了解一些代码。这就是为什么我很难理解这段代码的原因。

c assembly arm objective-c inline-assembly

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

使用gcc中的内联汇编从stdin扫描并打印到stdout

如何在内联汇编gcc中读取stdin并写入stdout,就像我们在NASM中这样做:

_start:
mov ecx, buffer ;buffer is a data word initialised 0h in section .data
mov edx, 03
mov eax, 03 ;read
mov ebx, 00 ;stdin
int 0x80
;Output the number entered
mov eax, 04 ;write
mov ebx, 01 ;stdout
int 0x80
Run Code Online (Sandbox Code Playgroud)

我尝试从内联汇编中的stdin读取,然后将输入分配给x:

#include<stdio.h>
int x;
int main()
{
    asm(" movl $5,  %%edx \n\t" " 
    movl $0,  %%ebx \n\t" " 
    movl $3,  %%eax \n\t" " 
    int $0x80 \n\t "
    mov %%ecx,x" 
    ::: "%eax", "%ebx", "%ecx", "%edx");

    printf("%d",x);  
    return 0;
} …
Run Code Online (Sandbox Code Playgroud)

c gcc nasm inline-assembly

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

汇编程序打包数据

我需要写一个用于在最小单元格内存中写入3个字母单词的置信码来说明这个图片,它说明了我需要的东西:

在此输入图像描述

我开始编写代码了:

    mov eax, dword ptr str[0]
    bsr cl, eax
    inc cl
    shl eax, cl
    push eax
    //
    mov eax, dword ptr str[1]
    pop ebx
    or eax, ebx
    push eax // unshifted
    //
    mov eax, dword ptr str[2]
    bsr cl, eax
    inc cl
    pop ebx
    shl ebx, cl
    or eax, ebx
    mov result, ebx
Run Code Online (Sandbox Code Playgroud)

但我得到-934608896(否定后
为00110111101101010000000000000000 )而不是1304526(0100111110011111001110)

x86 assembly inline-assembly

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