相关疑难解决方法(0)

为什么rbp和rsp称为通用寄存器?

根据英特尔在x64中,以下寄存器称为通用寄存器(RAX,RBX,RCX,RDX,RBP,RSI,RDI,RSP和R8-R15)https://software.intel.com/en-us/articles/介绍到x64组装.

在下面的文章中,写了RBP和RSP是专用寄存器(RBP指向当前堆栈帧的基础,RSP指向当前堆栈帧的顶部). https://www.recurse.com/blog/7-understanding-c-by-learning-assembly

现在我有两个相互矛盾的陈述.英特尔声明应该是值得信赖的,但是什么是正确的,为什么RBP和RSP被称为通用目的?

谢谢你的帮助.

assembly x86-64 cpu-registers

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

某些通用寄存器是否比其他寄存器更快?

在 x86-64 中,如果某些通用寄存器比其他寄存器更受欢迎,某些指令会执行得更快吗?

例如,mov eax, ecx执行速度会比mov r8d, ecx? 我可以想象后者需要一个 REX 前缀,这会使指令获取速度变慢?

使用rax而不是怎么样rcx?怎么样add还是xor?其他操作?较小的寄存器,如r15bvs al? alah?

AMD VS 英特尔?较新的处理器?旧处理器?指令组合?

澄清:某些通用寄存器是否应该优先于其他寄存器,它们是哪些?

performance x86 assembly x86-64 cpu-registers

11
推荐指数
2
解决办法
307
查看次数

为什么使用寄存器 R12 时 POP 很慢?

在最近的 Intel CPU 上,POP指令的吞吐量通常为每个周期 2 条指令。但是,当使用寄存器R12(或者RSP,除了前缀之外具有相同编码)时,如果指令通过传统解码器,吞吐量会下降到每个周期 1(如果 μops 来自 DSB,吞吐量保持在每个周期大约 2 )。

这可以使用nanoBench重现,如下所示:

sudo ./nanoBench.sh -asm "pop R12"
Run Code Online (Sandbox Code Playgroud)

在 Haswell 机器上的进一步实验表明:当在 1 和 4 之间添加时nops

sudo ./nanoBench.sh -asm "pop R12; nop;"
sudo ./nanoBench.sh -asm "pop R12; nop; nop;"
sudo ./nanoBench.sh -asm "pop R12; nop; nop; nop;"
sudo ./nanoBench.sh -asm "pop R12; nop; nop; nop; nop;"
Run Code Online (Sandbox Code Playgroud)

执行时间增加到 2 个周期。添加第 5 个时nop

sudo ./nanoBench.sh -asm "pop R12; nop; nop; nop; …
Run Code Online (Sandbox Code Playgroud)

performance x86 intel cpu-architecture micro-optimization

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

为什么 x86 16 位寻址模式没有比例因子,而 32 位版本有比例因子?

我试图找出 x86 16 位寻址模式(MASM 程序集)中不存在比例因子的原因。而32位和64位寻址模式都有比例因子。这背后是否有实际原因或者不需要它?如果您能解释一下,我将不胜感激。

可以组合不同组件来创建有效地址的所有可能方式:

Image of all possible ways different components can be combined to create an effective address

16 位和 32 位寻址模式之间的差异

Differences between 16- and 32-bit addressing modes

x86 assembly addressing-mode x86-16

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

x86操作码编码:sib字节

我目前正在尝试编写一个反汇编程序.我找到了以下操作码列表及其含义,所以我决定在运行时解析它:http: //mprolab.teipir.gr/vivlio80X86/pentium.txt

但我被困在操作码0x00:接下来是reg/modbyte.解析它对我来说不是什么大问题.但是我在使用Scale-Index-Byte时遇到问题:如果你实际上将esp指定为索引寄存器,它实际上意味着没有索引寄存器.这同样适用于ebp的基址寄存器.但我用c ++内联汇编程序尝试了它:可以编译:"add [ebp*2 + ebp],cl"

那么当使用ebp作为基址寄存器时,如何将ebp用作基址寄存器实际上意味着根本不使用基址寄存器!

x86 assembly disassembly

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

我会用什么编译器来编写机器语言?

出于兴趣,我想在机器代码中编写一个小程序.

我目前正在学习寄存器,ALU,总线和内存,我有点着迷,指令可以用二进制而不是汇编语言编写.

是否需要使用编译器?

最好是在OSX上运行的.

assembly machine-code

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

引用内存位置的内容.(x86寻址模式)

我有一个内存位置,其中包含一个我想要与另一个角色进行比较的角色(并且它不在堆栈的顶部,所以我不能只是pop它).如何引用内存位置的内容以便进行比较?

基本上我如何在语法上做到这一点.

x86 assembly masm addressing-mode

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

长度更改前缀 (LCP) 是否会导致简单 x86_64 指令停顿?

考虑一个简单的指令,例如

mov RCX, RDI          # 48 89 f9
Run Code Online (Sandbox Code Playgroud)

48 是 x86_64 的 REX 前缀。它不是LCP。但请考虑添加 LCP(用于对齐目的):

.byte 0x67
mov RCX, RDI          # 67 48 89 f9
Run Code Online (Sandbox Code Playgroud)

67 是地址大小前缀,在本例中用于没有地址的指令。该指令也没有立即数,并且不使用 F7 操作码(假 LCP 停止;F7 将是 TEST、NOT、NEG、MUL、IMUL、DIV + IDIV)。假设它也不跨越 16 字节边界。这些是 Intel优化参考手册中提到的 LCP 停顿情况。

该指令是否会导致 LCP 停顿(在 Skylake、Haswell 等上)?两个 LCP 怎么样?

我日常驾驶的是 MacBook。所以我无法访问 VTune,也无法查看 ILD_STALL 事件。还有其他方法可以知道吗?

performance assembly x86-64 cpu-architecture micro-optimization

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

如果我在 x86 AT&T 语法中省略了比例因子和索引寻址模式,会发生什么?

我是组装新手,我正在从头开始编程学习它。在第 41 页和第 42 页,该书讨论了索引寻址模式。

内存地址引用的一般形式是: ADDRESS_OR_OFFSET(%BASE_OR_OFFSET,%INDEX,MULTIPLIER)
所有字段都是可选的。要计算地址,只需执行以下计算:
FINAL ADDRESS = ADDRESS_OR_OFFSET + %BASE_OR_OFFSET + MULTIPLIER * %INDEX
ADDRESS_OR_OFFSET 和 MULTIPLIER 必须都是常量,而另外两个必须是寄存器。如果任何部分被遗漏,它只是在等式中用零代替。

所以我决定稍微玩一下这个。我写了下面的一段代码:

.code32
.section .data
str:
    .ascii "Hello world\0"

.section .text
.global _start
_start:
    movl $2, %ecx       # The index register.
    mov str(, %ecx, ), %bl
    movl $1, %eax
    int $0x80

Run Code Online (Sandbox Code Playgroud)

我希望得到 72(H 的 ASCII 代码)作为程序的退出结果,因为没有任何乘数(根据这本书,应该用零代替)。但令人惊讶的是,我得到了 108(l 的 ASCII 代码)。我认为这可能是.ascii一回事,并试图查看是否可以使用不同的数据类型获得不同的结果。我得到了相同的结果.byte

我尝试使用 AT&T 语法在 x86 程序集中查找索引寻址模式,但找不到任何有用的信息(可能是因为我不知道要搜索什么)。

有什么我遗漏的或者是书中的错误吗?鉴于我是该领域的新手,如果您详细说明,我真的很感激。

x86 assembly gnu-assembler att addressing-mode

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

NASM x86_64在32位模式下组装:为什么该指令产生RIP相对寻址代码?

[bits 32]
    global _start

    section .data
    str_hello       db  "HelloWorld", 0xa
    str_hello_length    db      $-str_hello

    section .text

    _start:

        mov ebx, 1              ; stdout file descriptor
        mov ecx, str_hello      ; pointer to string of characters that will be displayed        
        mov edx, [str_hello_length] ; count outputs Relative addressing
        mov eax, 4              ; sys_write
        int 0x80                ; linux kernel system call

        mov ebx, 0  ; exit status zero
        mov eax, 1  ; sys_exit
        int 0x80    ; linux kernel system call
Run Code Online (Sandbox Code Playgroud)

这里的基本要点是我需要将hello字符串的长度传递给linux的sys_write系统调用.现在,我很清楚我可以使用EQU,它会工作正常,但我真的想了解这里发生了什么.

所以,基本上当我使用EQU时,它会加载值,这很好.

str_hello_length equ $-str_hello …
Run Code Online (Sandbox Code Playgroud)

linux assembly x86-64 nasm relative-addressing

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