标签: gnu-assembler

Gnu Assembler(GAS)中的CFI指令用于什么?

在每一行之后似乎都有一个.CFI指令,而且这些ex..cfi_startproc,.cfi_endproc等等的变化很大. 这里更多.

    .file   "temp.c"
    .text
.globl main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    movl    $0, %eax
    leave
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
.globl func
    .type   func, @function
func:
.LFB1:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    movl    %edi, -4(%rbp)
    movl    %esi, %eax
    movb    %al, -8(%rbp)
    leave
    ret
    .cfi_endproc
.LFE1:
    .size   func, .-func
    .ident  "GCC: (Ubuntu 4.4.1-4ubuntu9) …
Run Code Online (Sandbox Code Playgroud)

assembly gnu-assembler

111
推荐指数
3
解决办法
4万
查看次数

GCC在x86,win32上的空程序的汇编输出

我编写空程序来惹恼stackoverflow程序员的地狱,不是.我正在探索gnu工具链.

现在以下对我来说可能太深了,但是为了继续执行空程序传奇,我已经开始检查C编译器的输出,GNU作为消耗的东西.

gcc version 4.4.0 (TDM-1 mingw32)
Run Code Online (Sandbox Code Playgroud)

test.c的:

int main()
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

gcc -S test.c

    .file   "test.c"
    .def    ___main;    .scl    2;  .type   32; .endef
    .text
.globl _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    call    ___main
    movl    $0, %eax
    leave
    ret 
Run Code Online (Sandbox Code Playgroud)

你能解释一下这里发生的事吗?这是我努力理解它.我使用了as手册和我的最小x86 ASM知识:

  • .file "test.c" 是逻辑文件名的指令.
  • .def:根据文档"开始定义符号名称的调试信息".什么是符号(函数名称/变量?)以及什么样的调试信息?
  • .scl:docs说"存储类可以标记符号是静态的还是外部的".这是我从C中知道的静态外部吗?什么是'2'?
  • .type:存储参数"作为符号表条目的类型属性",我不知道.
  • .endef: 没问题.
  • .text:现在这是有问题的,它似乎是一个叫做section的东西,我已经读过它的代码所在,但是文档并没有告诉我太多. …

c x86 gcc gnu-assembler tdm-mingw

55
推荐指数
3
解决办法
5594
查看次数

什么是注册%eiz?

在我使用以下转出的汇编代码中objdump:

lea    0x0(%esi,%eiz,1),%esi
Run Code Online (Sandbox Code Playgroud)

什么是注册%eiz?前面的代码是什么意思?

x86 assembly gnu-assembler objdump

52
推荐指数
3
解决办法
7933
查看次数

GAS:.cfi_def_cfa_offset的说明

我想解释一下GCC生成的汇编中.cfi_def_cfa_offset指令使用的值.我隐约知道.cfi指令涉及调用帧和堆栈展开,但我想更详细地解释为什么,例如,在编译以下C程序时GCC输出的汇编中使用值16和8的原因在我的64位Ubuntu机器上.

C程序:

#include <stdio.h>

int main(int argc, char** argv)
{
        printf("%d", 0);
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在源文件test.c上调用了GCC,如下所示:gcc -S -O3 test.c.我知道-O3可以实现非标准优化,但为了简洁起见,我想限制生成的程序集的大小.

生成的程序集:

        .file   "test.c"
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "%d"
        .text
        .p2align 4,,15
.globl main
        .type   main, @function
main:
.LFB22:
        .cfi_startproc
        subq    $8, %rsp
        .cfi_def_cfa_offset 16
        xorl    %edx, %edx
        movl    $.LC0, %esi
        movl    $1, %edi
        xorl    %eax, %eax
        call    __printf_chk
        xorl    %eax, %eax
        addq    $8, %rsp
        .cfi_def_cfa_offset 8
        ret
            .cfi_endproc
.LFE22:
        .size   main, .-main
        .ident  "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
        .section        .note.GNU-stack,"",@progbits …
Run Code Online (Sandbox Code Playgroud)

assembly callstack gnu-assembler dwarf

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

是否可以在Linux x86 GAS程序集中创建没有系统调用的线程?

在学习"汇编语言"(在使用GNU作为汇编程序的x86架构上的linux中)时,其中一个时刻就是使用系统调用的可能性.这些系统调用非常方便,有时甚至是必需的,因为您的程序在用户空间中运行.
然而,系统调用在性能方面相当昂贵,因为它们需要中断(当然还有系统调用),这意味着必须从用户空间中的当前活动程序到内核空间中运行的系统进行上下文切换.

我想说的是:我目前正在实现一个编译器(用于大学项目),我想要添加的一个额外功能是支持多线程代码以提高编译程序的性能.因为一些多线程代码将由编译器本身自动生成,所以这几乎可以保证其中也会有很少的多线程代码.为了获得性能,我必须确保使用线程可以实现这一点.

但我担心的是,为了使用线程,我必须进行系统调用和必要的中断.因此,微小的(自动生成的)线程将受到进行这些系统调用所花费的时间的极大影响,这甚至可能导致性能损失......

因此,我的问题是双重的(在其下面有一个额外的奖励问题):

  • 是否可以编写汇编代码,可以同时在多个内核上同时运行多个线程,无需系统调用?
  • 如果我有非常小的线程(在线程的总执行时间很小),性能损失,或者根本不值得努力,我会获得性能提升吗?

我的猜测是没有系统调用就不可能有多线程汇编程序代码.即使是这种情况,您是否有建议(甚至更好:一些实际代码)尽可能高效地实现线程?

linux assembly multithreading gnu-assembler

35
推荐指数
4
解决办法
3万
查看次数

NASM与GAS(实际差异)

我并没有试图提示英特尔与AT&T之争(无论如何,现在他们都支持英特尔语法)或者问哪一个本身"更好",我只是想知道选择其中一个的实际差异. .

基本上,当我几年前拿起一些基本的x86组件时,除了我正在阅读的那本书之外,我没有理由使用NASM - 这让我坚定但不由自主地进入了NASM阵营.从那时起,我使用汇编的原因很少,所以我没有机会尝试GAS.

请记住,它们都支持英特尔语法(我个人更喜欢),理论上至少应该生成相同的二进制文件(我知道它们可能不会,但意思不应该改变),有什么理由支持非此即彼?

是命令行选项吗?宏?非助记符关键字?或者是其他东西?

谢谢 :)

x86 assembly gnu-assembler nasm

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

如何在64位汇编程序中使用RIP相对寻址?

如何在AMD64架构的Linux汇编程序中使用RIP相对寻址?我正在寻找一个使用AMD64 RIP相对地址模式的简单示例(Hello world程序).

例如,以下64位汇编程序将与普通(绝对寻址)一起使用:

.text
    .global _start

_start:
    mov $0xd, %rdx

    mov $msg, %rsi
    pushq $0x1
    pop %rax
    mov %rax, %rdi
    syscall

    xor %rdi, %rdi
    pushq $0x3c
    pop %rax
    syscall

.data
msg:
    .ascii    "Hello world!\n"
Run Code Online (Sandbox Code Playgroud)

我猜测使用RIP相对寻址的相同程序将是这样的:

.text
    .global _start

_start:
    mov $0xd, %rdx

    mov msg(%rip), %rsi
    pushq $0x1
    pop %rax
    mov %rax, %rdi
    syscall

    xor %rdi, %rdi
    pushq $0x3c
    pop %rax
    syscall

msg:
    .ascii    "Hello world!\n"
Run Code Online (Sandbox Code Playgroud)

编译时,正常版本运行正常:

as -o hello.o hello.s && ld -s -o hello hello.o && ./hello
Run Code Online (Sandbox Code Playgroud)

但我无法使RIP版本正常工作. …

64-bit assembly x86-64 gnu-assembler

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

从c调用汇编函数

我正在尝试在程序集中使用函数,从C项目调用.这个函数应该调用一个libc函数printf(),但我一直遇到分段错误.

在.c文件中,我有函数的声明让我们说

int do_shit_in_asm()
Run Code Online (Sandbox Code Playgroud)

在我的.asm文件中

.extern printf
.section .data
         printtext:
              .ascii "test"
.section .text
.global do_shit_in_asm
.type do_shit_in_asm, @function

do_shit_in_asm:
    pushl %ebp
    movl %esp, %ebp
    push printtext
    call printf
    movl %ebp, %esp
    pop %ebp
ret
Run Code Online (Sandbox Code Playgroud)

任何指针评论将不胜感激.

as func.asm -o func.o

gcc prog.c func.o -o prog
Run Code Online (Sandbox Code Playgroud)

c linux assembly gnu-assembler

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

cltq在装配中做了什么?

0x0000000000400553 <main+59>:   mov    -0x4(%rbp),%eax
0x0000000000400556 <main+62>:   cltq   
0x0000000000400558 <main+64>:   shl    $0x3,%rax
0x000000000040055c <main+68>:   mov    %rax,%rdx
Run Code Online (Sandbox Code Playgroud)

事实上,我的程序很简单:

5   int main(int argc, char *argv[]) { 
6     int i = 0;
7     while(environ[i]) {
8       printf("%s\n", environ[i++]);
9     }
10    return 0;
Run Code Online (Sandbox Code Playgroud)

但是程序集输出很长:

Dump of assembler code for function main:
0x0000000000400518 <main+0>:    push   %rbp
0x0000000000400519 <main+1>:    mov    %rsp,%rbp
0x000000000040051c <main+4>:    sub    $0x20,%rsp
0x0000000000400520 <main+8>:    mov    %edi,-0x14(%rbp)
0x0000000000400523 <main+11>:   mov    %rsi,-0x20(%rbp)
0x0000000000400527 <main+15>:   movl   $0x0,-0x4(%rbp)
0x000000000040052e <main+22>:   jmp    0x400553 <main+59>
0x0000000000400530 <main+24>:   mov    -0x4(%rbp),%eax …
Run Code Online (Sandbox Code Playgroud)

x86 assembly gnu-assembler att

26
推荐指数
4
解决办法
4万
查看次数

海湾合作委员会:禁止使用某些登记册

这是一个奇怪的要求,但我觉得它有可能.我想要的是将一些编译指示或指令插入到我的代码区域(用C编写),以便GCC的寄存器分配器不会使用它们.

我知道我可以做这样的事情,这可能会为这个变量留下这个寄存器

register int var1 asm ("EBX") = 1984;
register int var2 asm ("r9") = 101;
Run Code Online (Sandbox Code Playgroud)

问题是我直接插入新指令(用于硬件模拟器),而GCC和GAS还没有识别出这些指令.我的新指令可以使用现有的通用寄存器,我想确保我保留了一些(即r12-> r15).

现在,我在一个模拟环境中工作,我想快速做我的实验.将来我会添加GAS并将内在函数添加到GCC中,但是现在我正在寻找快速修复.

谢谢!

c assembly gcc gnu-assembler register-allocation

22
推荐指数
4
解决办法
3866
查看次数