- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用 x86-64 gcc -Og -std=gnu99 -xc 编译。
在.L3的第二行(addl(%rdi,%rcx,4),%eax
),为什么不直接使用寄存器% edx
加到和的时候?
添加 (%rdi,%edx,4), %eax
int sum_arr(int arr[], int nelems) {
int sum = 0;
for (int i = 0; i < nelems; i++) {
sum += arr[i];
}
return sum;
}
sum_arr:
movl $0, %edx
movl $0, %eax
jmp .L2
.L3:
movslq %edx, %rcx
addl (%rdi,%rcx,4), %eax
addl $1, %edx
.L2:
cmpl %esi, %edx
jl .L3
rep ret
最佳答案
正如 4386427 之前的回答所指出的,您不能在一个有效地址中混用 32 位和 64 位寄存器。 CPU 不支持。所以 addl (%rdi,%edx,4), %eax
将不可编码。
要将i
用作有效地址的索引部分,我们需要在64 位寄存器中使用它。由于 i
是带符号的 int
类型,因此编译器使用 movsx
对其进行符号扩展。并且它使用一个单独的寄存器%rcx
,这样%edx
可以继续保存变量i
的值,让调试器更容易检查此值(例如,gdb 中的 print i
)。
事实证明,我们可以证明 i
在这个函数中总是非负的。初始 movl $0, %edx
also zeros out the high half of %rdx
, 从那时起它将保持为零,所以实际上 %rdx
总是包含变量 i
的正确 64 位值。因此我们可以使用 addl (%rdi, %rdx, 4), %eax
代替,并省略 movsx
。不过,编译器可能没有在这种优化级别上进行推论。
(也可以使用地址大小覆盖前缀的有效地址中的所有 32 位寄存器,因此 addl (%edi, %edx, 4), %eax
是一个可编码的指令,但它不会工作,因为它会截断 %rdi
中指针 arr
的高 32 位。因此,地址大小覆盖在64 位代码。)
关于arrays - 为什么汇编代码在加总和之前将值从 %edx 复制到 %rcx?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68609600/
我正在读一本书:[xchg rax, rax]。以下是本书的 0x03 片段,我无法理解这一点。 sub rdx,rax sbb rcx,rcx and rcx,rdx
64 位 Windows 似乎使用 rcx = r8 = &PEB 调用 exe 的入口点和 rdx = r9 = &entrypoint好像入口点被声明 entrypoint(PEB *peb, v
我有 30 个未开封的 Lego Mindstorms 套件,我很想在我的编程入门类(class)中使用它们,以便在年底时做一些简单的机器人技术。我们在类里面使用 Python,所以我希望有一种方法可
使用 x86-64 gcc -Og -std=gnu99 -xc 编译。 在.L3的第二行(addl(%rdi,%rcx,4),%eax),为什么不直接使用寄存器% edx 加到和的时候? 添加 (%
我有一个用 MASM64/ML64 组装的 X64 ASM 例程。它是一个独立的叶函数,不是内联汇编。它用于 Visual Studio 解决方案中的 C/C++ 程序。 我在 MSDN 上找到了两个
我有一个用 MASM64/ML64 组装的 X64 ASM 例程。它是一个独立的叶函数,不是内联汇编。它用于 Visual Studio 解决方案中的 C/C++ 程序。 我在 MSDN 上找到了两个
为了在 Linux 系统启动时自动运行程序,我必须修改/etc/rcX.d,在/etc/init.d 中添加一些指向脚本的链接,我有两个问题: 目录名“/etc/rcNum.d”中的数字是什么意思?当
这是 ../sysdeps/x86_64/memcpy.S 中的一行,在这行之后我遇到了 VM 崩溃,所以我需要知道发生了什么。基本上我知道它类似于将 rsi 复制到 rcx。但这是否意味着 rsi
这个问题在这里已经有了答案: Why do x86-64 Linux system calls modify RCX, and what does the value mean? (1 个回答) 关
void UART_init(void){ ANSELB = 0; //set PORT B to digital port TRISBbits.TRISB5 = 1; //s
我有这个函数指针和这段代码: 0x0000555555556e80 : push %rbp 0x0000555555556e81 : mov %rsp,%rbp 0x0000
我有这个函数指针和这段代码: 0x0000555555556e80 : push %rbp 0x0000555555556e81 : mov %rsp,%rbp 0x0000
上下文: Linux 64。 GCC 4.8.2(带 -O3 -march=native) 我左手下的x86_64 abi,在第21页打开。 C代码: int main (int argc, ch
这个问题在这里已经有了答案: Linux x64: why does r10 come before r8 and r9 in syscalls? (2 个答案) 关闭 3 年前。 根据 Syste
我用我的爱好 x86_64 UEFI 内核达到了用户代码调用系统代码的目的,但它会在 0x1B:0x0(0x1B 是用户模式代码段选择器)处生成错误代码 0 的一般保护错误。单步执行,我意识到 SYS
我想我明白 movzbl (%rdi, %rcx, 1) , %ecx 意思是“将零扩展字节移到长”,并表示将 ecx 扩展为 32 位,但我不完全确定语法 (%rdi, %rcx, 1) 指的是什么
我还没有找到解决问题的方法。我想知道的是我如何在 C++ 中做到这一点。 我有一个指向位置 mov rcx, qword ptr [0xAddress] 的地址。然后我需要找到一种方法,仅使用 C++
x64 寄存器是否可以互换,从某种意义上说,使用它们的一种组合的任何指令都可以与其他任何组合一起使用?除了名称之外,是否存在性能差异或任何其他考虑因素使它们彼此不同? 最佳答案 不是。虽然大多数 x8
我正在使用.NetCore 3 和 Swagger 5.0.0-rc4。我正在尝试使用 Swagger 上传文件(图像),但它不起作用,因为 IOperationFilter 甚至 Swashbuck
这个问题已经有答案了: What do the E and R prefixes stand for in the names of Intel 32-bit and 64-bit registers
我是一名优秀的程序员,十分优秀!