首先,什么尺寸eax,ax,ah和同行,在64位架构?如何访问单个寄存器的字节以及如何访问所有64位寄存器的8个字节?
我非常喜欢x86-64(x64)和Itanium处理器.
第二,在新的调用约定中,使用四个寄存器来保存函数调用中前四个参数的正确方法是什么?
为什么没有特定的寄存器来访问寄存器的其他部分(16-32)?
像啊或al一样访问ax寄存器的8位部分.

我刚刚查看了彼得·科德斯(Peter Cordes)的回答,他说,
如果读取标志,则部分标志停顿会发生,如果它们确实发生的话。P4永远不会有部分标志停顿,因为它们永远不需要合并。相反,它具有错误的依赖关系。几个答案/评论混淆了术语。它们描述了一个错误的依赖关系,但随后将其称为部分标志停顿。这是由于仅写入一些标志而导致的速度下降,但是术语“部分标志停顿”是指必须合并部分标志写入时在SnB之前的Intel硬件上发生的情况。英特尔SnB系列CPU插入一个额外的uop来合并标志而不会停顿。Nehalem和更早的失速约7个周期。我不确定AMD CPU会受到多大的损失。
我感觉我还不明白什么是“部分国旗摊位”。我怎么知道一个人发生了?除了读取标志的某些时间之外,什么触发事件?合并标志是什么意思?在什么情况下会“写一些标志”,但不会发生部分标志合并?我需要了解哪些有关旗位的知识才能理解它们?
我想在GHC Haskell编译器中实现C的uint-to- doublecast 的等价物.我们已经实现了int-到- double使用FILD或CVTSI2SD.是否有这些操作的无符号版本,或者我应该uint将转换前的最高位置零(从而丢失范围)?
我正在学习 64 位 nasm,我通过执行以下操作来汇编 .nasm 文件,该文件仅包含 64 位寄存器
nasm -f elf64 HelloWorld.nasm -o HelloWorld.o
Run Code Online (Sandbox Code Playgroud)
并链接它执行以下操作
ld HelloWorld.o -o HelloWorld
Run Code Online (Sandbox Code Playgroud)
程序运行正确,甚至在我运行命令时说它是 64 位 ELF file,但是当我使用objdump或gdb反汇编可执行文件时,我在代码中作为 64 位寄存器放置的寄存器在以下情况下显示为 32 位寄存器:已拆卸。(示例:rax在源代码中显示为eax反汇编时的样子)
为什么是这样?
这种情况不仅仅发生在一台计算机上,而且这是一个新问题,以前没有这样做过。
你好世界.nasm:
global _start
section .text
_start:
mov rax, 1
mov rdi, 1
mov rsi, hello_world
mov rdx, length
syscall
mov rax, 60
mov rdi, 11
syscall
section .data
hello_world: db 'Hello World',0xa
length: equ $-hello_world
Run Code Online (Sandbox Code Playgroud)
拆解后的HelloWorld:
...
00000000004000b0 <_start>:
4000b0: b8 …Run Code Online (Sandbox Code Playgroud) 我知道这是一个非常简单的问题,但我找不到答案.x86汇编中的寄存器(eax,ebx edx等)是否已签名或未签名?如果它们是默认签名的,那么计算机如何知道将寄存器视为无符号的,例如我们将变量声明为unsigned int?谢谢!
我想看看当unsigned long long被分配了一个值的幕后发生了什么unsigned int.我做了一个简单的C++程序来尝试它并将所有io移出main():
#include <iostream>
#include <stdlib.h>
void usage() {
std::cout << "Usage: ./u_to_ull <unsigned int>\n";
exit(0);
}
void atoiWarning(int foo) {
std::cout << "WARNING: atoi() returned " << foo << " and (unsigned int)foo is " <<
((unsigned int)foo) << "\n";
}
void result(unsigned long long baz) {
std::cout << "Result as unsigned long long is " << baz << "\n";
}
int main(int argc, char** argv) {
if (argc != 2) usage();
int …Run Code Online (Sandbox Code Playgroud) 为了学习汇编,我正在查看GCC使用-S命令为一些简单的c程序生成的汇编.我有一个add函数,它接受一些int和一些char并将它们加在一起.我只是想知道为什么char参数被压缩到8个字节(pushq)?为什么不只推一个字节?
.file "test.c"
.text
.globl add
.type add, @function
add:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl %edx, -12(%rbp)
movl %ecx, -16(%rbp)
movl %r8d, -20(%rbp)
movl %r9d, -24(%rbp)
movl 16(%rbp), %ecx
movl 24(%rbp), %edx
movl 32(%rbp), %eax
movb %cl, -28(%rbp)
movb %dl, -32(%rbp)
movb %al, -36(%rbp)
movl -4(%rbp), %edx
movl -8(%rbp), %eax
addl %eax, %edx
movl -12(%rbp), %eax
addl %eax, %edx
movl -16(%rbp), %eax
addl %eax, …Run Code Online (Sandbox Code Playgroud) 我试图用GCC Inline Assembly做一些事情,在这种情况下,做一个Syscall,但我想强制使用64位寄存器(rax,rdi,rsi,...)而不是32位寄存器(eax,edi, ...),但我尝试了很多方法,没有.
void syscall(uint64_t arg1, uint64_t arg2) {
// arg1 -> rax arg2 -> rdi
__asm__("syscall" : : "a" (arg1), "D" (arg2));
}
Run Code Online (Sandbox Code Playgroud)
当我编译我得到:
mov eax, 60
syscall
Run Code Online (Sandbox Code Playgroud)
我正处于一个函数中,所以"edi"正在从参数中得到,但就像你可以看到的那样是"eax",我想使用rax.
如何强制使用64位寄存器而不是32位寄存器?
我开始学习汇编程序,这对我来说并不合乎逻辑.
为什么我不能在寄存器中使用多个更高的字节?
我理解rax- > eax- > 的历史原因ax,所以让我们关注新的 64位寄存器.例如,我可以使用r8和r8d,但为什么不r8dl和r8dh?同样适用于r8w和r8b.
我最初的想法是,我可以使用8个r8b在同一时间寄存器(就像我可以做的al,并ah在同一时间).但我不能.并且使用r8b使完整的r8寄存器"忙".
这提出了一个问题 - 为什么?如果您不能同时使用其他部件,为什么还只需要使用寄存器的一部分?为什么不保持只r8忘记下部?