Assembly 是否可以在x64操作系统上运行x86程序集?

Assembly 是否可以在x64操作系统上运行x86程序集?,assembly,architecture,operating-system,x86,x86-64,Assembly,Architecture,Operating System,X86,X86 64,最近,我决定值得尝试一下基本的x86汇编,这样可以更容易地调试程序等等。所以我(大约一周前)开始学习x86汇编,当时,我将我的计算机升级到8GB ram,很明显我的x86 Windows XP安装浪费了所有内存,现在,我运行的是x64 Windows 7拷贝,因此,问题是: 是否可以在x64操作系统上使用x86程序集?它是否可以在模拟器中正常运行?或者我应该学习x64组装吗?当然可以。大多数程序仍然是32位的,在64位Windows系统上运行良好。这些程序是机器语言,它与汇编语言有一对一的映射(

最近,我决定值得尝试一下基本的x86汇编,这样可以更容易地调试程序等等。所以我(大约一周前)开始学习x86汇编,当时,我将我的计算机升级到8GB ram,很明显我的x86 Windows XP安装浪费了所有内存,现在,我运行的是x64 Windows 7拷贝,因此,问题是:


是否可以在x64操作系统上使用x86程序集?它是否可以在模拟器中正常运行?或者我应该学习x64组装吗?

当然可以。大多数程序仍然是32位的,在64位Windows系统上运行良好。这些程序是机器语言,它与汇编语言有一对一的映射(并且可以很容易地反汇编成x86汇编代码)

可以使用x86吗 x64操作系统上的程序集? 它能在模拟器中正常运行吗

是的,这是可能的&它将正常运行。指令集架构总是向后兼容的

x86-64中的寄存器:


(来源:)

例如: 在这里您可以看到,
rax
是新的64位通用寄存器,但您仍然可以使用
eax
,因为它指的是
rax
的较低32位

还是应该学习x64组装

x86-32体系结构是x86-64的子集。这就像你首先学习了x86,然后去寻找x86-64汇编的新功能。
一旦您学习了x86 asm。这将是一个有用的资源:

如果编译选项:

CONFIG_IA32_EMULATION=y
一切就绪

这是由大多数理智的发行版完成的,包括Ubuntu 14.04

32位仿真当然只有在x86-64处理器设计为通过内核知道如何使用的32位仿真模式与32位可执行文件向后兼容的情况下才可能实现

你必须担心的另一件事是库:要编译32位程序,你需要32位库。在Ubuntu 14.04 AMD64上:

sudo apt-get install gcc-multilib
然后我们可以用hello world轻松地测试它:

#include <stdio.h>
#include <stdlib.h>

int main() {
    puts("hello world");
    return EXIT_SUCCESS;
}
其中打印:

hello world
以及:

确认它是32位的:

ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=358f7969deeb2f24a8dd932a0d296887af4eae30, not stripped

谢谢你,我可以毫不担心地知道r在rax中代表什么?我知道e代表什么extended@kizzx2:
r
代表寄存器
e
表示扩展。如果你去其他ISA,你会发现像r1、r2、r3这样的寄存器名…视觉效果总是让答案更好。答案很好,数字可以理解。x86 ISA总是向后兼容,因为这是它的关键功能/卖点(而且快速x86-64 CPU的存在也让它继续运行)。一些AARC64芯片已经放弃了对ARM32模式的支持。因此,一般来说,指令集架构并不总是向后兼容的。MIPS64r6甚至在现有模式下重新组织了一些操作码,因此它是一个单独的不兼容CPU,仅在asm源代码级别与早期的MIPS兼容;Windows内核中的仿真层的行为类似于Linux,具有
CONFIG\u IA32\u emulation=n
。它不能运行32位二进制文件,也不能从64位代码运行32位
int0x80
系统调用(没有人首先应该这样做,但新手手工编写的asm有时会这样做)。我想在这个问题上释放一点(这样做似乎非常相关,而且不会劫持):世界上有很多用于x86-32的资源。在装配级别上,32/64之间似乎没有太多差异。考虑到32种材料的丰富性,是否值得挖掘出64种资源,并在这一点上真正专注于64种材料(假设一个人想学习64种),或者,因为它(至少看起来)重要的概念都是32位的,只有像64位寄存器这样的东西才是真正重要的,把我自己限制在32位就可以了。但是,如果您转到编译器,它会发生变化。调用约定和ABI不同,X86_64上的强制SSE2意味着实际使用了它。另外,像PIC这样的东西也很不一样。尽管如此,这些差异还是可以处理的。马可,我不太清楚我是否理解:你是说你认为64与32相比,概念上的差异是如此微不足道,以至于学习汇编的人可以安全地忽略它们,只专注于32,而不用担心在迁移到64时必须取消学习“旧”方法?你真的不需要放弃任何东西。学习堆栈arg(传统32位)和寄存器arg(64位)调用约定都是有意义的,并且64位调用约定在寄存器用完后必须使用堆栈arg,例如,对于具有6个以上整数arg的函数。首先学习32位并不是一个坏计划;有些事情在那里更简单。(但在现代调用约定中,以4字节为单位保持16字节堆栈对齐比以64位为单位的8字节推送更难看。)
file a.out
ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=358f7969deeb2f24a8dd932a0d296887af4eae30, not stripped