Questions tagged «x86»

x86是派生自Intel 8086 CPU的体系结构。x86系列包括32位IA-32和64位x86-64架构,以及传统的16位架构。关于后者的问题应标记为[x86-16]和/或[emu8086]。如果您的问题特定于64位x86-64,请使用[x86-64]标记。对于x86 FPU,使用标签[x87]。对于SSE1 / 2/3/4 / AVX *,也请使用[sse],以及适用的[avx] / [avx2] / [avx512]中的任何一个

3
CPU特权环:为什么不使用环1和2?
有关x86 CPU特权环的几个问题: 为什么大多数操作系统不使用Ring 1和Ring 2?仅仅是为了保持与其他体系结构的代码兼容性,还是有更好的理由? 是否有任何实际使用这些环的操作系统?还是完全不使用它们?
102 x86  cpu  privileges 

5
“ FS” /“ GS”寄存器的用途是什么?
因此,我知道以下寄存器及其用途是什么: CS =代码段(用于IP) DS =数据段(用于MOV) ES =目标段(用于MOVS等) SS =堆栈段(用于SP) 但是,以下寄存器打算用于什么? FS =“文件段”? GS = ??? 注意:我不是在问任何特定的操作系统,而是在问它们打算由CPU使用什么(如果有的话)。

11
现代硬件上的浮点数与整数计算
我正在用C ++进行一些性能至关重要的工作,并且我们目前正在使用整数计算来解决那些固有的浮点问题,因为它“更快”。这会引起很多烦人的问题,并增加了很多烦人的代码。 现在,我记得读过有关浮点计算如何如此缓慢的信息,大约在386天左右,我相信(IIRC)有一个可选的协同处理器。但是,如今在使用指数级更复杂,功能更强大的CPU时,如果进行浮点或整数计算,那么“速度”没有区别吗?特别是由于与导致流水线停滞或从主内存中获取某些内容相比,实际的计算时间很小? 我知道正确的答案是在目标硬件上进行基准测试,什么是测试此硬件的好方法?我编写了两个微型C ++程序,并将它们的运行时间与Linux上的“时间”进行了比较,但是实际的运行时间变化太大(对我在虚拟服务器上运行没有帮助)。我一整天都没有运行数百个基准测试,制作图表等,我是否可以做一些事情来对相对速度进行合理测试?有什么想法或想法吗?我完全错了吗? 我使用的程序如下,它们在任何方面都不相同: #include <iostream> #include <cmath> #include <cstdlib> #include <time.h> int main( int argc, char** argv ) { int accum = 0; srand( time( NULL ) ); for( unsigned int i = 0; i < 100000000; ++i ) { accum += rand( ) % 365; } …


5
EBP帧指针寄存器的用途是什么?
我是汇编语言的初学者,并且注意到编译器发出的x86代码即使在释放/优化模式下也可以将EBP寄存器用于其他用途时,通常也会保持帧指针。 我理解为什么帧指针可能使代码更易于调试,并且如果alloca()在函数中调用它可能是必需的。但是,x86的寄存器非常少,当其中一个寄存器足够用时,使用其中两个寄存器来保持堆栈帧的位置对我来说是没有意义的。为什么即使在优化/发布版本中也忽略帧指针还是​​一个坏主意?


2
x86分页如何工作?
这个问题的目的是填补有关该主题的大量免费信息的空白。 我相信一个好的答案将适合一个大的SO答案,或者至少可以包含几个答案。 主要目标是向完整的初学者提供足够的信息,以便他们可以自己阅读手册,并能够理解与分页相关的基本OS概念。 建议的准则: 答案应该是初学者友好的: 具体的,但可能简化的示例非常重要 欢迎使用所示概念的应用程序 引用有用的资源是好的 欢迎对操作系统如何使用分页功能进行少量讨论 欢迎使用PAE和PSE说明 欢迎小小进取x86_64 相关问题以及为什么我认为它们不是伪造的: x86页表如何工作?:标题几乎与此问题相同,但正文会询问与cr3和TLB有关的特定问题。这个问题是这个问题的一部分。 x86虚拟化如何工作:正文仅要求提供资源。


6
为什么英特尔将内部RISC内核隐藏在其处理器中?
从Pentium Pro(P6微体系结构)开始,英特尔重新设计了其微处理器,并根据旧的CISC指令使用了内部RISC内核。从Pentium Pro开始,所有CISC指令都被划分为较小的部分,然后由RISC内核执行。 一开始,对我来说很明显,英特尔决定隐藏新的内部架构,并迫使程序员使用“ CISC shell”。由于这一决定,英特尔可以完全重新设计微处理器架构而不会破坏兼容性,这是合理的。 但是我不明白一件事,为什么英特尔仍然将内部RISC指令集隐藏了这么多年?他们为什么不让程序员像使用旧的x86 CISC指令集那样使用RISC指令? 如果Intel保持了向后兼容性这么长的时间(我们仍然在64位模式旁边拥有虚拟8086模式),为什么它们不允许我们编译程序,因此它们将绕过CISC指令并直接使用RISC内核?这将为自然放弃如今不推荐使用的x86指令集开辟一种自然的方式(这是Intel决定在内部使用RISC内核的主要原因,对吧?)。 看到新的Intel“ Core i”系列,我发现它们仅扩展了CISC指令集,添加了AVX,SSE4等。



2
什么是“ rep; 没事;” 在x86汇编中意味着什么?它与“暂停”指令相同吗?
什么rep; nop意思 与pause指示相同吗? 是否与rep nop(不含分号)相同? 简单nop指令有什么区别? 它在AMD和Intel处理器上的行为是否有所不同? (奖金)这些说明的正式文件在哪里? 这个问题的动机 在讨论另一个问题的评论后,我意识到我不知道rep; nop;x86(或x86-64)汇编的含义。而且我在网上也找不到很好的解释。 我知道这rep是一个前缀,表示“重复下一个指令cx时间”(或者至少在旧的16位x86汇编中是这样)。根据这一维基百科汇总表,似乎rep只能与使用movs,stos,cmps,lods,scas(但也许是对新的处理器去掉这个限制)。因此,我认为rep nop(没有分号)会重复一个nop操作cx时间。 但是,经过进一步的搜索,我变得更加困惑。似乎rep; nop和pause 映射到完全相同的操作码,并且pause行为与刚刚不同nop。2005年的一些旧邮件说了不同的话: “尽量不要消耗太多功率” “仅用2字节编码就相当于'nop'。” “这在英特尔上是神奇的。就像'nop,但让其他HT兄弟运行一样'” “在Intel上暂停,在Athlon上快速填充” 由于这些不同的意见,我无法理解正确的含义。 它是在Linux内核(两个正在使用的i386和x86_64的),这条评论在一起:/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */它也正在贝尔托斯使用,具有相同的注释。

3
使用gdb在指定的可执行文件之外单步执行汇编代码会导致错误“找不到当前函数的边界”
我不在gdb的目标可执行文件之外,甚至没有对应于该目标的堆栈。无论如何,我都想单步执行,以便我可以验证汇编代码中发生的事情,因为我不是x86汇编方面的专家。不幸的是,gdb拒绝执行此简单的程序集级调试。它允许我在适当的断点处设置和停止,但是一旦我尝试单步执行,gdb就会报告错误“找不到当前函数的边界”,并且EIP不会更改。 额外细节: 机器代码是由gcc asm语句生成的,我从objdump -d的输出将其复制到了正在执行的内核内存位置。我不介意使用加载程序将目标代码加载到重定位地址的简单方法,但是请记住,加载必须在内核模块中完成。 我想另一种选择是产生一个伪造的内核模块或调试信息文件以提供给gdb,使它相信该区域在程序代码内。gdb在内核可执行文件本身上运行良好。 (对于那些真正想知道的人,我是在运行时将代码插入VMware VM内的Linux内核数据空间中,然后通过gdb调试它,通过VMware Workstation的内置gdb存根对内核进行远程调试。注意,我不是在编写内核漏洞利用;我是写原型的安全研究生。) (我可以在程序集中的每条指令上设置一个断点。这可以工作,但是一段时间后会变得很费力,因为x86汇编指令的大小各不相同,并且每次重新启动时程序集的位置都会改变。)

3
Win32上将double类型转换为unsigned int会截断为2,147,483,648
编译以下代码: double getDouble() { double value = 2147483649.0; return value; } int main() { printf("INT_MAX: %u\n", INT_MAX); printf("UINT_MAX: %u\n", UINT_MAX); printf("Double value: %f\n", getDouble()); printf("Direct cast value: %u\n", (unsigned int) getDouble()); double d = getDouble(); printf("Indirect cast value: %u\n", (unsigned int) d); return 0; } 输出(MSVC x86): INT_MAX: 2147483647 UINT_MAX: …

7
是否可以告诉分支预测变量跟随分支的可能性有多大?
为了清楚起见,我在这里不打算进行任何形式的可移植性,因此任何将我与特定机器绑定在一起的解决方案都可以。 基本上,我有一条if语句,它将在99%的时间中将其评估为true,并试图提高性能的最后一个时钟,我是否可以发出某种编译器命令(使用GCC 4.1.2和x86 ISA,如果重要)告诉分支预测器它应该为该分支缓存?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.