我有一些关于装配的问题,我正在学习,我很困惑.
bx和bp和ss和sp?书中说这bx是基址寄存器,bp是基指针.这是否意味着他们是一回事?mov ax, bx,mov ax, [bx],mov ax, bp和mov ax, [bp]?disp索引寻址模式意味着什么?比如mov al, disp[bx]?还是mov al, disp[si]?这本书没有解释的含义disp.寄存器在CPU中不是RAM吗?
请原谅我的英文,这不是我的第一个语言.
一直在进行装配任务,而且大部分时间我都很了解装配.或者至少对这项任务来说已经足够了.但这个mov声明让我感到沮丧.如果有人能解释这个mov语句如何操作寄存器值,我真的很感激.
mov(%ebx,%eax,4),%eax
PS我无法通过基本搜索找到这种特定类型的mov语句,所以如果我错过了它并且正在提问,我会道歉.
该程序(来自 Jonathan Bartlett 的《从头开始编程》)循环访问内存中存储的所有数字,并将.long最大的数字放入 EBX 寄存器中,以便在程序完成时查看。
.section .data
data_items:
.long 3, 67, 34, 222, 45, 75, 54, 34, 44, 33, 22, 11, 66, 0
.section .text
.globl _start
_start:
movl $0, %edi
movl data_items (,%edi,4), %eax
movl %eax, %ebx
start_loop:
cmpl $0, %eax
je loop_exit
incl %edi
movl data_items (,%edi,4), %eax
cmpl %ebx, %eax
jle start_loop
movl %eax, %ebx
jmp start_loop
loop_exit:
movl $1, %eax
int $0x80
Run Code Online (Sandbox Code Playgroud)
我不确定(,%edi,4)这个程序的目的。我读到逗号是为了分隔,而 4 是为了提醒我们的计算机数据项中的每个数字都是 4 个字节长。既然我们已经用.long声明了每个数字都是4个字节,为什么我们还需要在这里再声明一次呢?另外,有人可以更详细地解释这两个逗号在这种情况下的用途吗?
我正在查看此站点的一些代码示例:
看着它我看到他们有一些指令,而不是直接使用内存位置,他们使用标签,例如,在alive.asm中:
lda ypos,x
Run Code Online (Sandbox Code Playgroud)
而ypos是
ypos:
dcb $00,$02,$20,$02,$40,$02,$60,$02
dcb $80,$02,$a0,$02,$c0,$02,$e0,$02
dcb $00,$03,$20,$03,$40,$03,$60,$03
dcb $80,$03,$a0,$03,$c0,$03,$e0,$03
dcb $00,$04,$20,$04,$40,$04,$60,$04
dcb $80,$04,$a0,$04,$c0,$04,$e0,$04
dcb $00,$05,$20,$05,$40,$05,$60,$05
dcb $80,$05,$a0,$05,$c0,$05,$e0,$05
Run Code Online (Sandbox Code Playgroud)
我知道标签的不同取决于汇编程序,但我假设它正在通过该列表,但它的特殊性如何工作
在 x86_64 中,fs 和 gs 寄存器涉及有限形式的分段。就以fs为例,fs寄存器、FSBase MSR是如何协同工作生成有效地址的呢?
如果我更改 fs 基数而不更改 fs,会发生什么情况?还是更改 fs 基础会自动更改 fs?
如果我更改 fs 寄存器而不更改 fs 基数会怎样?如何影响有效地址计算?
我们可以举一个简单的例子
mov %fs:(%eax), %ebx
Run Code Online (Sandbox Code Playgroud) assembly x86-64 cpu-registers memory-segmentation addressing-mode
我正在编写一个应该绝对没有开销的委托库。因此,尽可能快地访问函数指针很重要。
所以我的问题是:访问速度是否取决于班级中的成员位置?我听说最重要的成员应该是成员声明中的第一个成员,这对我来说很有意义,因为这意味着this类的指针指向与重要成员相同的地址(假设是非虚拟类)。而如果重要成员将在任何其他位置,CPU 将不得不通过添加this和类布局中的偏移量来计算它的位置。
另一方面,我知道编译器将该地址表示为 a qword-ptr,其中包含偏移量的信息。
所以我的问题归结为:解决 a 是否qword-ptr需要一个恒定的时间,或者如果偏移量不是,它会增加0吗?行为在不同平台上是否保持相同?
c++ performance micro-optimization class-members addressing-mode
在运算中将寄存器括在括号中到底会产生什么差异?
例如:
movl (%edx), %eax
Run Code Online (Sandbox Code Playgroud)
相对
movl %edx, %eax
Run Code Online (Sandbox Code Playgroud)
先感谢您!
我正在exercism.org 上浏览 x86-64 教程。我在 Linux 上使用 NASM,生成 ELF 二进制文件。只有一点 C 代码可以在测试工具中调用我的汇编代码。他们的构建系统-pie在 LDFLAGS 和-fPIECFLAGS 中指定(除其他外,但我认为这些是最相关的)。因此,我需要(并且想了解)一个使用 PIC 的解决方案,它需要 RIP 相对寻址。
我有一个rdi名为 的 8 字节 (qword) 值数组的索引 (in ) values。我只想获取偏移量处的地址,以便将mov其指向的值存入寄存器。或者我会接受mov直接接受该值。
我试过这个:
lea rbx, [rel values + rdi * 8]
Run Code Online (Sandbox Code Playgroud)
我的理解是,这将查看该部分中rip的地址(相对于 ),然后它将添加正确的偏移量()并将其放入 中。valuesdatardi * 8rbx
但这会产生下一个错误:
Run Code Online (Sandbox Code Playgroud)/usr/bin/ld: space_age.o: relocation R_X86_64_32S against `.data' can not be used when making a PIE object; recompile with -fPIE
我理解这 …
在实模式和 32 位保护模式下,16 位寻址用于通过 ModR/M 字节来引用存储器。此寻址仅在使用旧前缀的 i386 指令中受支持,在 x86-64 指令中完全不受支持。
然而,ModR/M 字节也被 8 位特定操作码使用,这让我怀疑原始16 位 x86 指令集中是否存在 8 位寻址。尽管 8 位地址非常有限,但完全可以使用不同的操作码以与 16 位指令相同的方式对此类指令进行编码。
例如,代替
add (bx, si), ax
Run Code Online (Sandbox Code Playgroud)
你会有
add (bl, dh), al
Run Code Online (Sandbox Code Playgroud)
很难找到任何 i386 之前的文档,所以我一无所知。这曾经被支持过吗?
我正在编写简单的程序然后分析它们。今天我写了这个:
#include <stdio.h>
int x;
int main(void){
printf("Enter X:\n");
scanf("%d",&x);
printf("You enter %d...\n",x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它被编译成这样:
push rbp
mov rbp, rsp
lea rdi, s ; "Enter X:"
call _puts
lea rsi, x
lea rdi, aD ; "%d"
mov eax, 0
call ___isoc99_scanf
mov eax, cs:x <- don't understand this
mov esi, eax
lea rdi, format ; "You enter %d...\n"
mov eax, 0
call _printf
mov eax, 0
pop rbp
retn
Run Code Online (Sandbox Code Playgroud)
我不明白什么cs:x意思。
我使用 Ubuntu x64、GCC 10.3.0 和 IDA …
addressing-mode ×10
assembly ×9
x86 ×4
att ×3
x86-64 ×3
6502 ×1
c++ ×1
disassembly ×1
ida ×1
label ×1
masm ×1
nasm ×1
performance ×1
relocation ×1
x86-16 ×1