Assembly X86_64-汇编-为什么位移不是64位?
我正在阅读《英特尔x86_64指南》第一卷,以更新内存寻址的工作原理 尽管如此 3.7.5指定偏移量 存储器地址的偏移部分可以直接指定为静态值(称为位移),也可以通过由以下一个或多个组件组成的地址计算来指定: •位移-8、16或32位值 我在Agner Fog的汇编指南中读到,当与(r/e)ax寄存器一起使用时,64位绝对寻址是可能的 所以Assembly X86_64-汇编-为什么位移不是64位?,assembly,x86-64,memory-address,Assembly,X86 64,Memory Address,我正在阅读《英特尔x86_64指南》第一卷,以更新内存寻址的工作原理 尽管如此 3.7.5指定偏移量 存储器地址的偏移部分可以直接指定为静态值(称为位移),也可以通过由以下一个或多个组件组成的地址计算来指定: •位移-8、16或32位值 我在Agner Fog的汇编指南中读到,当与(r/e)ax寄存器一起使用时,64位绝对寻址是可能的 所以 是否可以使用64位地址的绝对寻址到jmp、mov和call(与所有寄存器一起),或者我必须继续使用Base+displacement组合?我认为x86体系结
是否可以使用64位地址的绝对寻址到jmp、mov和call(与所有寄存器一起),或者我必须继续使用Base+displacement组合?我认为x86体系结构没有64位位移或偏移
原因很简单:它们提供的编程的“易用性”并不经常发生。从统计上看,您需要的大多数偏移量都非常小。当您需要64位偏移量(很少)时,您始终可以使用ADD指令进行模拟,而几乎没有性能损失。做64位偏移的晶体管最好用在做其他事情上。只有从累加器到累加器的移动有一个64位绝对地址变量。
所有其他移动仅限于32位置换方法。请注意,
mov absolute\u addr64,%rax
仅在rax
作为目标时可用。mov$imm64,%reg
可用于任何寄存器。看到了吗 当AMD设计AMD64架构时,他们基本上说2GB的代码应该足够每个人使用。(每个可执行文件和每个共享库;未静态链接在一起的事物之间的调用通常需要通过完整的64位地址进行间接寻址。) 介绍x86-64 System V ABI(用于非Windows的所有设备)的小型、中型和大型代码模型
- 小:每个跳转、调用和内存位移的正常32位相对位移。(已知所有符号都位于
和0
之间)2^31-2^24-1
- 中:小代码,但数据部分分为两部分:常规部分和大型部分(
,.ldata
,lrodata
).lbss
movabs
指令
访问大型静态数据并将地址加载到寄存器中,但
保留了小代码模型的优点,便于操作
小数据和文本部分的地址(特别需要
分支机构)
默认情况下,只有大于65535字节的数据才会放入大数据部分
- 大型:
movabs
指令,如
中等代码模型,甚至用于处理文本中的地址
节。此外,分支时还需要间接分支
指向与当前指令指针的偏移量为
不知道
可以避免对文本的限制
在中小型模型中细分程序
到多个共享库中,因此此模型仅限于
如果单个函数的文本大于
中等型号允许
中等PIC需要movabs/lea/add
生成大于32位位移的RIP相对地址
大型PIC也需要它来处理全局偏移表和程序链接表。因为您正在阅读手册。。为什么不查一下呢?@harold:我没有多个CPU/品牌的拱门。我需要一个全面可靠的答案。这就是为什么:)添加指令?有意思,你会怎么做?我怀疑我是否会这样做,因为它会导致另一条指令,甚至是一条1 cpu周期的指令,这是一种浪费。如果你想用64位位移执行索引操作,你必须将位移添加到基址。所以,在一个寄存器中,添加64位常量,然后间接加载或存储目标地址。在更特殊的情况下,如果64位值是直接地址,您可以简单地将其加载到寄存器中,然后执行间接寻址。是的,做加法需要额外的指令。实际上,你不会经常这样做,所以这没关系。好吧,非常感谢你的精确性。我认为你不能添加64位立即值,但你可以添加存储在内存中的64位值,或者将64位立即值移动到寄存器中,然后将该寄存器用作地址的一部分。我想知道当使用段时的偏移量,例如用于访问“每线程”变量的FS或GS。rand的种子值就是其中之一。@rcgldr:这是正确的,即使是
添加$immediate,%rax
也只能与扩展符号imm32
一起使用。如果希望将常量内联到指令流中,而不是作为数据加载,则可以movabs$imm64,%rax
。(). 最佳方案:将64b位移保存在寄存器中,在另一个寄存器中计算索引,并将该索引用作添加的dest/1st src。