标签: gnu-assembler

不能在Gnu AS表达式中使用'&'运算符

我想得到一个变量的地址和4096(它对应于其内存页面的地址).由于这是可以离线计算的东西,我做了一些看起来像这样的事情(v是变量,vpage应该包含其页面的地址):

    .data
    v:        .zero 0x100
    vpage:  .long v & 0xfffff000
Run Code Online (Sandbox Code Playgroud)

尝试使用x86汇编程序编译此文件会导致以下错误:

test.S: Assembler messages:
test.S:3: Error: invalid sections for operation on `v' and `L0'
Run Code Online (Sandbox Code Playgroud)

为什么GAS拒绝计算这个?现在奇怪的部分:用"+"替换'&',代码将编译,链接后甚至可以正确计算地址.任何有关此行为原因或如何解决此问题的提示都将非常受欢迎.

assembly gnu-assembler

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

Gnu汇编(GAS)优化

我实际上是在学习装配,我和Gas一起去了,但问题是:

1)我只知道英特尔语法,我在一个页面中看到,在某些情况下,具有intel语法的Gas不是很好.这是正确还是我错了?我在谈论这个网站:

http://wiki.osdev.org/FASM

2)然后我也看到(我不记得页面)事实气体可以在几个架构中组装也减慢了组装的程序.这样对吗?

3)你推荐哪种汇编程序可以产生高度优化的代码?我在其他问题中看到,在某些情况下,每个汇编程序都可以转换为不同的操作码.我在YASM,FASM,GAS和NASM之间,但其他推荐被接受.知道FASM非常快......

非常感谢!保持这个伟大的社区!

optimization assembly gnu-assembler fasm

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

GCC不在函数调用中保存/恢复保留寄存器

我在GCC有一个场景给我带来了问题.我得到的行为不是我期望的行为.总结一下这种情况,我提出了一些x86-64的新指令,它们是在硬件模拟器中实现的.为了测试这些指令,我正在使用现有的C源代码并使用十六进制对新指令进行手动编码.因为这些指令与现有的x86-64寄存器交互,所以我使用input/output/clobber列表来声明GCC的依赖关系.

发生的事情是,如果我调用一个函数,例如printf,则不会保存和恢复相关寄存器.

例如

register unsigned long r9  asm ("r9")  = 101;
printf("foo %s\n", "bar");
asm volatile (".byte 0x00, 0x00, 0x00, 0x00" : /* no output */ : "q" (r9) );
Run Code Online (Sandbox Code Playgroud)

101被分配给r9,内联汇编(本例中为假)依赖于r9.这在没有printf的情况下正确运行,但是当它存在时,GCC不会保存和恢复r9,并且在调用自定义指令时会有另一个值.

我想也许GCC可能秘密地将赋值更改为变量 r9,但是当我这样做时

asm volatile (".byte %0" : /* no output */ : "q" (r9) );
Run Code Online (Sandbox Code Playgroud)

看看汇编输出,确实使用的是%r9.

我正在使用gcc 4.4.5.您认为可能会发生什么?我认为GCC将始终在函数调用中保存和恢复寄存器.有什么方法可以强制执行吗?

谢谢!

编辑:顺便说一句,我正在编译这样的程序

gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test
Run Code Online (Sandbox Code Playgroud)

c assembly gcc gnu-assembler register-allocation

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

LLVM上的内联ASM中的"无效符号重新定义"

我在Xcode(4.5.2)中有一个使用Debug配置构建的项目.但是,现在我已经切换到构建Release配置,我遇到了一个问题:我的一个内联汇编函数正在收到错误Invalid symbol redefinition.谷歌搜索该错误消息发现我有一些人有编译器错误,但没有关于它意味着什么的信息.这是函数,带有注释的错误行:

inline int MulDivAdd(int nNumber,
                int nNumerator,
                int nDenominator,
                int nToAdd)
{
    int nRet;

    __asm__ __volatile__ (
        "mov    %4,     %%ecx   \n"
        "mov    %1,     %%eax   \n"
        "mull   %2              \n"
        "cmp    $0,     %%ecx   \n"
        "jl     __sub           \n"
        "addl   %%ecx,  %%eax   \n"
        "adc    $0,     %%edx   \n"
        "jmp    __div           \n"
    "__sub:                     \n"    // "Invalid symbol redefinition"
        "neg    %%ecx           \n"
        "subl   %%ecx,  %%eax   \n"
        "sbb    $0,     %%edx   \n"
    "__div:                     \n"    // "Invalid symbol redefinition"
        "divl   %3              \n"
        "mov    %%eax,  %0      \n" …
Run Code Online (Sandbox Code Playgroud)

c++ assembly gnu-assembler llvm clang

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

为什么海湾合作委员会生产ANDL $ -16?

我需要一些帮助来理解GCC为什么这么做

main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp   # ???
    subl    $48, %esp    # ???
    movl    $8, 16(%esp)        
    movl    $4, 20(%esp)
Run Code Online (Sandbox Code Playgroud)

为什么先减去16再减去48呢?这样做会不容易subl $64, %esp

x86 assembly 32-bit gnu-assembler disassembly

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

汇编程序何时更好地使用符号扩展重定位(如R_X86_64_32S)而不是像R_X86_64_32那样的零扩展?

作为一个具体的例子,在GAS 2.24上移动地址:

mov $s, %eax
s:
Run Code Online (Sandbox Code Playgroud)

后:

as --64 -o a.o a.S
objdump -Sr a.o
Run Code Online (Sandbox Code Playgroud)

使用零扩展:

0000000000000000 <s-0x5>:
   0:   b8 00 00 00 00          mov    $0x0,%eax
                        1: R_X86_64_32  .text+0x5
Run Code Online (Sandbox Code Playgroud)

但内存访问:

mov s, %eax
s:
Run Code Online (Sandbox Code Playgroud)

编译以签署扩展名:

0000000000000000 <s-0x7>:
   0:   8b 04 25 00 00 00 00    mov    0x0,%eax
                        3: R_X86_64_32S .text+0x7
Run Code Online (Sandbox Code Playgroud)

在这种特定情况下,或者一般情况下,是否有理由使用?我不明白汇编程序如何能够对任何一种情况做出更好的假设.

NASM 2.10.09仅R_X86_64_32用于上述两种情况.更新:在2.11之后的一个边缘nasm commit 6377180产生相同的Gas输出,这看起来像Ross提到的一个bug.

我已经解释了我认为我理解的内容R_X86_64_32S:https://stackoverflow.com/a/33289761/895245

assembly x86-64 gnu-assembler nasm elf

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

1:汇编语言是什么意思?

我正在阅读RISC-V测试模式的源代码.在riscv-test.h中有一个宏定义,

我想知道1:这段代码意味着什么:

#define RVTEST_CODE_BEGIN                                               \
        .section .text.init;                                            \
        .align  6;                                                      \
        .weak stvec_handler;                                            \
        .weak mtvec_handler;                                            \
        .globl _start;                                                  \
_start:                                                                 \
        /* reset vector */                                              \
        j reset_vector;                                                 \
        .align 2;                                                       \
trap_vector:                                                            \
        /* test whether the test came from pass/fail */                 \
        csrr t5, mcause;                                                \
        li t6, CAUSE_USER_ECALL;                                        \
        beq t5, t6, write_tohost;                                       \
        li t6, CAUSE_SUPERVISOR_ECALL;                                  \
        beq t5, t6, write_tohost;                                       \
        li t6, CAUSE_MACHINE_ECALL;                                     \
        beq t5, t6, write_tohost;                                       \
        /* if …
Run Code Online (Sandbox Code Playgroud)

assembly gnu-assembler riscv

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

为什么不能在多个函数中定义相同的本地标签?

要在多个函数中定义相同的本地标签:

    .text
    .globl main
func:
    push %rbp
    mov %rsp, %rbp
.a:
    leave
    ret

main:
    push %rbp
    mov %rsp, %rbp
.a:
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

奇怪地得到错误:

$ clang -c main.s
main.s:13:1: error: invalid symbol redefinition
.a:
^
Run Code Online (Sandbox Code Playgroud)

当我使用yasm时,它允许多个功能使用相同的本地标签。你有什么线索吗?

syntax assembly x86-64 gnu-assembler

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

获取内联GNU汇编程序中的字符串长度

我正在重新学习我在很老的MS-DOS机器上使用的汇编程序!

这是我对该功能应该是什么样的理解.它编译但崩溃了SIGSEGV试图把时0xffffffffecx.

代码在具有32位Debian 9的VM中运行.任何帮助将不胜感激.

    int getStringLength(const char *pStr){

        int len = 0;
        char *Ptr = pStr;

        __asm__  (
            "movl %1, %%edi\n\t"
            "xor %%al, %%al\n\t"
            "movl 0xffffffff, %%ecx\n\t"
            "repne scasb\n\t"
            "subl %%ecx,%%eax\n\t"
            "movl %%eax,%0"
            :"=r" (len)     /*Output*/
            :"r"(len)       /*Input*/
            :"%eax"         /*Clobbered register*/


    );

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

linux x86 gcc gnu-assembler inline-assembly

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

为什么AT&T jmp * bar用SIB字节组装成机器代码?指令中没有使用寄存器

我在x86机器上有以下绝对间接跳转指令:

ff 24 25 30 10 60 00

产生于:

jmp *bar

但是我在解码它的第二个和第三个字节时遇到了麻烦。

第二个应该是Mod R / M字段。因此它翻译为:

00 100 100

含义:

00 -没有位移的内存(但是它具有恒定的地址,这不是“位移”吗?)

100(12月4日)-扩展操作。代码(FF / 4 => JMP r / m32)

100-?? SIB?但是该指令中没有使用寄存器


PS一些上下文:

Breakpoint 4, test () at test.s:13
13              jmp     *bar
(gdb) disassemble /r
Dump of assembler code for function test:
   0x000000000040051b <+0>:     c7 04 25 30 10 60 00 2f 05 40 00        movl   $0x40052f,0x601030
=> 0x0000000000400526 <+11>:    ff 24 25 30 10 60 00    jmpq …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 gnu-assembler att

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