标签: x86-64

为什么以下 x86_64 程序集会出现分段错误?

到目前为止,我一直在学习编写一些 x86_64 程序集。我读到可以减去 RSP 来向下增长堆栈并分配空间,所以我编写了以下代码:

push %rbp
movq %rsp, %rbp
subq $16, %rsp
movq $200, -8(%rsp)
movq $300, -16(%rsp)
popq %rbp
retq
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这将创建一个函数,在其中设置堆栈帧,然后在堆栈上分配 16 个字节,并将 -8 和 -16 的值分别设置为 200 和 300。但是,当我使用 gcc 运行此程序时,出现分段错误。不过,如果我删除sub程序的一部分,它就可以完美运行。我想我误解了一些东西,那么这里到底发生了什么?

assembly x86-64

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

如何将标签推入可重定位共享库的堆栈中,其对象应使用 -fPIC 进行编译?

我正在使用从汇编代码组装的多个目标文件来制作可重定位共享库(所有编译都应使用 -fPIC 和 -DPIC)。

在我的代码中我有push label说明。当我使用一切看起来都很好将汇编代码组装成目标文件时-fPIC -DPIC,但是当我想使用目标文件创建共享库时,我收到了消息relocation R_X86_64_32S against '.text' can not be used when making a shared object; recompile with -fPIC

我确信问题出在这些push label说明上,因为当我删除它们时,错误就会消失。

关于如何组装它有什么想法吗?

顺便说一句,我的平台是采用 Intel x86_64 架构的 Linux,编译器gcc采用 GAS 语法。我对 64 位库感兴趣。

assembly x86-64 shared-libraries

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

了解 x86-64 调用操作数

我正在查看radare2 中的一些测试代码,但我无法理解反汇编程序如何确定调用指令如何跳转到的位置。考虑一下:

r2

在 0x00001090 处,puts() 被调用。我想自己解析与该指令相关的二进制文件 (e89bffffff),因此我通过 lib capstone 运行它并得到了以下结果:

顶点

所以我们可以看到实际的操作数是0xfb0。然后在 rasm2 中我们有:

# rasm2 -a x86 -b 64 -d e8a1ffffff
call 0xffffffffffffffa6
Run Code Online (Sandbox Code Playgroud)

这是不同的。我预计 libcapstone 和 rasm2 具有相同的输出。

我的主要问题是,如何解释 0xfb0 (或 0xffffffffffffffa6)来获取下一条指令地址?就我而言,根据雷达,sym.imp.puts 位于 0x00001030。

x86 assembly x86-64

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

L2 行填充是否总是在查找时触发?

L2是非排除性的,这是一个有据可查的事实,这意味着 L2 不必包含 L1DCache 拥有的所有行。

\n\n

L1d miss (Read, RFO) 是否也错过了 L2 填充 L1d 行而不填充相应的 L2 行?英特尔 mans 中有对此有任何解释吗?更新:有。Intel Vol.3,有关内存类型的部分。

\n\n

或者用另一种方式重新表述这个问题:缺少 L2 的查找是否总是会导致其行被填充?

\n\n

经过一番挖掘后,我自己发现了答案。它是回写内存类型的属性,而不是缓存级别

\n\n
\n

回写 (WB) \xe2\x80\x94 对系统内存的写入和读取均被缓存。读取来自缓存命中时的缓存行;读取未命中导致\n 缓存已满。

\n
\n

x86 assembly x86-64 cpu-architecture cpu-cache

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

为什么push指令会改变rsp的值?

我正在检查 Ericksons Hacking: The Art of Exploitation 中的这段代码片段:

\n
void test_function(int a, int b, int c, int d) {\n        int flag;\n        char buffer[10];\n        flag = 31337;\n        buffer[0] = \'A\';\n}\n\nint main() {\n        test_function(1, 2, 3, 4); \n}\n
Run Code Online (Sandbox Code Playgroud)\n
void test_function(int a, int b, int c, int d) {\n        int flag;\n        char buffer[10];\n        flag = 31337;\n        buffer[0] = \'A\';\n}\n\nint main() {\n        test_function(1, 2, 3, 4); \n}\n
Run Code Online (Sandbox Code Playgroud)\n

我在 main 和 test_function 处设置了断点。\n当中断 main 时,我得到以下输出:

\n
gcc -g stack_example.c\n\ngdb -q ./a.out\n\ngef\xe2\x9e\xa4list main\n\n\n     0x555555555192 …
Run Code Online (Sandbox Code Playgroud)

c assembly x86-64

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

汇编部分 .code 和 .text 的行为不同

我是汇编新手,从我了解到的情况.code与 相同.text,但下面的代码将使用.code.

segment .data
    msg db "hello, world", 0xa
    len equ $ - msg

section .text
    global _start

_start:
    mov edx, len
    mov ecx, msg

    mov ebx, 1
    mov eax, 4
    int 0x80

    mov ebx, 0
    mov eax, 1
    int 0x80

Run Code Online (Sandbox Code Playgroud)
nasm -f elf64 -o hello.o hello.s 
ld -s -o hello hello.o
hello, world

sed -i s/.text/.code/ ./hello.s
nasm -f elf64 -o hello.o hello.s 
ld -s -o hello hello.o
./stack.sh: line 8:  4621 Segmentation …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 nasm elf

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

这个汇编函数如何返回值?

我用 C 语言编写了一个非常简单的函数,它使用strlen()from<string.h>返回变量的长度char*

int length(char *str) {

    return strlen(str);
}
Run Code Online (Sandbox Code Playgroud)

以下是相应的 x86_64 程序集objdump -M intel -d a.out

00000000000011a8 <length>:
    11a8:   f3 0f 1e fa             endbr64 
    11ac:   55                      push   rbp
    11ad:   48 89 e5                mov    rbp,rsp
    11b0:   48 83 ec 10             sub    rsp,0x10
    11b4:   48 89 7d f8             mov    QWORD PTR [rbp-0x8],rdi
    11b8:   48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
    11bc:   48 89 c7                mov    rdi,rax
    11bf:   e8 ac fe ff ff …
Run Code Online (Sandbox Code Playgroud)

c assembly x86-64 calling-convention

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

程序如何知道在堆栈上为局部变量分配多少空间?

在这个简单的函数中,为局部变量分配了空间。然后,变量被初始化并被printf调用以输出它们。

000000000040056a <func>:
  40056a:       55                      push   rbp                     ; function prologue
  40056b:       48 89 e5                mov    rbp,rsp                 ; function prologue
  40056e:       48 83 ec 10             sub    rsp,0x10                ; deallocating space for local variables
  400572:       8b 4d fc                mov    ecx,DWORD PTR [rbp-0x4] ; variable initialization
  400575:       8b 55 f8                mov    edx,DWORD PTR [rbp-0x8] ; variable initialization
  400578:       8b 45 f4                mov    eax,DWORD PTR [rbp-0xc] ; variable initialization
  40057b:       89 c6                   mov    esi,eax                 ; string stuff
  40057d:       bf 34 06 40 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly x86-64 stack-frame

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

C 中的内联汇编

我正在用 c 语言编写一个国际象棋引擎,速度至关重要。国际象棋引擎基于 unsigned long long,我将其表示为 u64,并且它严重依赖于最低有效位扫描。到目前为止,我一直在使用 gcc 函数 __builtin_ctzll ,它做得很好。然而,我使用 gcc -S -O2 为这个独立函数生成了汇编代码。它给了我以下内容:

xorl     %eax, %eax
rep bsfq %rdi, %rax
cltq
ret
Run Code Online (Sandbox Code Playgroud)

然而经过一番调查似乎代码

rep bsfq %rdi, %rax
ret
Run Code Online (Sandbox Code Playgroud)

在我的国际象棋程序中做了完全相同的事情。然而现在速度慢了约 20%。它应该更快,因为它的指令更少。然而,原始的 __builtin_ctzll 内联在我的 C 代码中。这是我的自定义汇编代码运行速度比原始代码慢的原因吗?因为当我声明函数 ctzll 时,我当然不能在 c 中内联声明它,除非我有定义(不在汇编代码中)。

是否有另一种方法来优化汇编指令,或者我应该尝试直接在 c 中内联 asm 的新汇编代码?

c assembly gcc x86-64 micro-optimization

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

使用每个标签地址,.o 文件的总大小会增加 24 个字节(加上 8 个字节(总共 32 个字节))

在我的 FASM 项目(对象)中,我尝试创建一个跳转表并用于dq每个跳转地址,但有一个问题!
对于每个dq .jmp1(跳转地址定义),.jmp1我的最终 .o 文件的总大小将添加 24 个字节(加上地址的 8 个字节(总共 32 个字节))!
那额外的 24 个字节是什么?有什么办法可以避免吗?这种情况仅发生在目标文件中,而不发生在可执行文件中!

它定义了 32 个字节,而不是每个跳转地址 8 个字节!问题是什么?

format ELF64

section '.text'

func:
        lea     rax, [8*rax+.jmp_table]

 .jmp1:

 .jmp_table:
        dq .jmp1 ; 8 bytes + 24 bytes !!! (to .o total size)
        dq .jmp1 ; 8 bytes + 24 bytes !!! (to .o total size)   
Run Code Online (Sandbox Code Playgroud)

但是当我创建一个可执行文件时,每个文件dq只需要 8 个字节(这是我所期望的)......

format ELF64 EXECUTABLE

segment readable executable

func:
        lea     rax, [8*rax+.jmp_table]

 .jmp1:

 .jmp_table: …
Run Code Online (Sandbox Code Playgroud)

assembly executable x86-64 object-files fasm

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