标签: x86-64

为什么引导加载程序只能接受 16 位程序集

自己写MBR的时候,需要告诉nasm用16bit汇编,不知道为什么2020年一定要用16bit汇编来写bootloader。

为什么我们不能用现代 x64 程序集开发引导加载程序?

assembly x86-64 bootloader x86-16

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

在 MUSL 的 x86_64 __syscall_cp_asm 包装器中的系统调用之前,在堆栈上保存传入 pthread 地址的目的是什么?

这是来自 musl 的源代码:

 1  __syscall_cp_asm:
 2  __cp_begin:
 3      mov (%rdi),%eax
 4      test %eax,%eax
 5      jnz __cp_cancel

 6      mov %rdi,%r11

 7      mov %rsi,%rax
 8      mov %rdx,%rdi
 9      mov %rcx,%rsi
10      mov %r8,%rdx
11      mov %r9,%r10
12      mov 8(%rsp),%r8
13      mov 16(%rsp),%r9

14      mov %r11,8(%rsp)

15      syscall
16  __cp_end:
17      ret
18  __cp_cancel:
19      jmp __cancel
Run Code Online (Sandbox Code Playgroud)

我很好奇第 6 行和第 14 行的目的是什么(从链接的来源重新编号)。

根据我的理解,代码的开头测试了作为第一个参数传递的指针的目标(第 3-5 行),然后第 6 行将指针移动到r11,第 14 行然后将它移动到使用的堆栈上的位置传递第 7 个参数。

这似乎没有用。这些动作有什么作用吗?

assembly x86-64 musl

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

为 64 位可执行文件手动生成的 PE 标头中的图像库出错

我想使用 NASM 构建自定义便携式可执行文件。使用命令获取可执行文件后,nasm -f bin program.asm -o program.exe它崩溃并给出类似于此的错误

在此处输入图片说明

你可以在下面看到代码。

bits 64
%define BASE  400000h
ALIGNMENT equ 512
%define SECTALIGN  8192
STD_OUTPUT_HANDLE   equ -11
NULL                equ 0

%define ROUND(v, a) (((v + a - 1) / a) * a)
%define ALIGNED(v) (ROUND(v, ALIGNMENT))
%define RVA(obj) (obj - BASE)

section header progbits start=0 vstart=BASE

mz_hdr:
    dw "MZ"                       ; DOS magic
    times 0x3a db 0               ; [UNUSED] DOS header
    dd RVA(pe_hdr)                ; address of PE header

pe_hdr:
    dw "PE",0                     ; PE …
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 nasm portable-executable

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

在这种情况下,为什么编译器使用 32 位寄存器来传递指向 amd64 linux 上的函数的指针

在此处输入图片说明我正在调试一个带有修改过的boringssl 的chrome。它总是有一个SegmentFault。我发现问题是

EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
Run Code Online (Sandbox Code Playgroud)

反汇编代码:

callq EC_KEY_get0_group
mov %eax,%edi
callq EC_GROUP_get_curve_name
Run Code Online (Sandbox Code Playgroud)

的返回类型EC_KEY_get0_group是一个EC_GROUP*指针,但它是EC_GROUP_get_curve_name由一个 32 位寄存器传递给的。

指针被截断并导致 SegmentFault。为什么编译器会生成这样的代码?是否有任何编译器选项可以避免这种情况?

c ssl assembly x86-64 chromium

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

了解这个 x86 汇编函数的作用,递归

我在这里有这个 Assembly 函数,并且多次运行它试图了解它的作用和模式是什么。在理解它的模式方面,我遇到了砖墙。任何形式的指导在这里都值得赞赏。

   0x0000555555555cbe <+0>: push   %rbx
   0x0000555555555cbf <+1>: mov    %edx,%eax
   0x0000555555555cc1 <+3>: sub    %esi,%eax
   0x0000555555555cc3 <+5>: mov    %eax,%ebx
   0x0000555555555cc5 <+7>: shr    $0x1f,%ebx
   0x0000555555555cc8 <+10>: add    %eax,%ebx
   0x0000555555555cca <+12>: sar    %ebx
   0x0000555555555ccc <+14>: add    %esi,%ebx
   0x0000555555555cce <+16>: cmp    %edi,%ebx
   0x0000555555555cd0 <+18>: jg     0x555555555cda <func4+28>
   0x0000555555555cd2 <+20>: cmp    %edi,%ebx
   0x0000555555555cd4 <+22>: jl     0x555555555ce6 <func4+40>
   0x0000555555555cd6 <+24>: mov    %ebx,%eax
   0x0000555555555cd8 <+26>: pop    %rbx
   0x0000555555555cd9 <+27>: retq  
   0x0000555555555cda <+28>: lea    -0x1(%rbx),%edx
   0x0000555555555cdd <+31>: callq  0x555555555cbe <func4>
   0x0000555555555ce2 <+36>: add    %eax,%ebx
   0x0000555555555ce4 <+38>: jmp …
Run Code Online (Sandbox Code Playgroud)

assembly reverse-engineering x86-64 cpu-registers

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

ASM x64 函数指针未返回正确值

我在汇编中的函数指针有问题,即使我的函数返回一个负数,它总是设置rax为一个正数,我做了一个最小的可重现示例,它使用一个比较两个整数的函数,它做同样的事情:

ASM 功能代码 [编辑]:

global foo

section .data
msg: db `superior\n`
msg_len: equ $-msg

section .text
foo:
    push rbx
    mov rbx, rdi
    mov rdi, 2
    mov rsi, 1
    sub rsp, 8  ; align the stack frame
    call rbx
    add rsp, 8
    test rax, rax   ;[EDIT] correct: test eax, eax
    js  bar
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, msg_len
    syscall

bar:
    mov rdi, 1
    mov rsi, 2
    sub rsp, 8  ; same here
    call …
Run Code Online (Sandbox Code Playgroud)

c assembly function-pointers x86-64 nasm

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

组装中的“对齐堆栈”是什么意思?

堆栈对齐在 ASMx64 中是如何工作的?什么时候需要在函数调用前对齐堆栈,需要减去多少?

我不明白这样做的目的是什么。我知道还有其他关于这个的帖子,但对我来说还不够清楚。例如:

extern foo
global bar

section .text
bar:
  ;some code...
  sub  rsp, 8     ; Why 8 (I saw this on some posts) ? Can it be another value ? Why do we need to substract?
  call foo        ; Do we need to align stack everytime we call a function?
  add  rsp, 8
  ;some code...
  ret
Run Code Online (Sandbox Code Playgroud)

assembly x86-64 calling-convention memory-alignment stack-pointer

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

计算前导/尾随 1/0 的效率有什么不同吗?

我正在设计一个带前缀的可变长度整数。

Rust 有计算前导和尾随 1 和 0 的方法:https : //doc.rust-lang.org/std/primitive.u64.html#method.leading_zeros

这些方法在 x86_64、arm32 和 arm64 上的效率有什么不同吗?

例如,如果计算尾随的 1 比尾随的零更快,我将使用 xxxx0111 而不是 xxxx1000 作为长度编码字节(在本例中,对于后面的三个字节)。

arm bit-manipulation x86-64 rust varint

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

如何通过操作码或反汇编查找使用哪种形式的指令?

https://uops.info/和 Agner Fog 的指令表,甚至英特尔自己的手册这样的网站,都列出了相同指令的各种形式。例如add m, r(在 Agner 的表格中)或add (m64, r64)在 uops.info 上,或ADD r/m64, r64在英特尔的手册中(https://www.felixcloutier.com/x86/add)。


这是我在 Godbolt 上运行的一个简单示例

__thread int a;
void Test() {
    a+=5;
}
Run Code Online (Sandbox Code Playgroud)

添加是add DWORD PTR fs:0xfffffffffffffffc,0x5。它以操作码开头64 83 04 25

有几种方法可以编写我的真实代码,但我想查找这可能需要多少个周期以及其他信息。我怎么找到这个指令的参考?我尝试在https://uops.info/table.html 中输入“add”并检查我的架构。但我不知道哪个条目是正在使用的指令。

现在在这种特定情况下,我猜测操作码是Add m64, r64但我不知道fs:在地址之前使用是否有任何惩罚,或者是否有办法查看操作码,以便我可以确认我正在查看正确的参考

assembly x86-64 machine-code disassembly micro-architecture

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

是否指定在 x64 上推送堆栈指针时会发生什么?

我在 x64 上用汇编编程,我打算在堆栈中推送一个地址。我打算编写push %rsp,但是,由于此指令更改了 的值%rsp,我不确定将推送什么值。

具体来说,如果我运行以下命令:

movq $0x10, %rsp
pushq %rsp
Run Code Online (Sandbox Code Playgroud)

内存地址是否0x8包含0x100x8?这个处理器是依赖的​​还是所有 x64 处理器的标准?

assembly callstack x86-64 instructions

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