leaq 的第一个操作数必须是内存地址,第二个操作数必须是寄存器吗?

     2023-02-16     98

关键词:

【中文标题】leaq 的第一个操作数必须是内存地址,第二个操作数必须是寄存器吗?【英文标题】:Must the first operand of leaq be a memory address and the second operand be a register? 【发布时间】:2018-10-25 22:09:06 【问题描述】:

在ATT汇编语言中,使用leaq指令时,它的第一个操作数必须是内存地址而不是寄存器或常量(前缀$)吗?它的第二个操作数必须是寄存器吗?我从阅读 Computer Systems: a Programmer's Perspective 中获得了这种印象,并且从未见过与我的猜测不同的示例。谢谢。

【问题讨论】:

是的,没错。如有疑问,请查阅官方指令集参考。请注意,内存地址当然可以使用寄存器或位移(没有$,因为那将是立即数)。 谢谢。我在网上找了一个参考文档,但我不确定它在哪里。 Intel® 64 and IA-32 Architectures Software Developer Manuals PS:使用 intel 语法而不是 at&t 所以你必须做一些脑力劳动:) @Jester 谢谢。什么样的脑力劳动? @fuz,您可能想删除该评论并重试。 【参考方案1】:

是的,没错。虽然在技术上可以对具有两个寄存器操作数的lea 进行编码,但这样的编码是无效的并导致#UD 异常。详情请见this reference 或this one。

【讨论】:

【参考方案2】:

即使它是可编码的,你也永远不想使用它。

如果你想把一个常量放在一个寄存器中,你永远不应该使用leamov $1234, %eaxlea 1234, %eax(disp32 寻址模式中的绝对地址)更短且更高效。

LEA 用于静态地址的唯一用例是具有 RIP 相对寻址模式的 64 位代码,例如 lea symbol(%rip), %rax(7 个字节),在 mov $symbol, %eax(5 个字节)由于您需要而无法使用的情况下与位置无关的代码,和/或地址不适合 32 位零扩展立即数。

请参阅Difference between movq and movabsq in x86-64 了解为什么mov $symbol, %rdi 不是最佳选择。


在 32 位代码中,lea symbol, %edi 为 6 个字节(操作码 + modrm + disp32),并且在英特尔 Sandybridge 系列 CPU 上仅运行一个端口 1 或端口 5。 (https://agner.org/optimize/)

mov $symbol, %edi 为 5 个字节 (opcode + imm32 short form with no ModRM byte),可在任何 ALU 端口上运行。

同样适用于 16 位代码:mov $symbol, %di 是 3 个字节,而 lea symbol, %di 是 4 个字节,具有相同的执行端口差异。 (或者在 NASM 语法中,lea di, [symbol]mov di, symbol,或 GAS 中的 mov di, OFFSET symbol .intel_syntax 或 MASM。)


不过,LEA 对 base=register 寻址模式很有用。如果地址适合 32 位符号扩展 disp32,则类似于 lea symbol(%rdi), %rax

或用于任意移位和添加用法,例如 lea 123(%rdi, %rdi, 2), %eax 执行 eax = 3*edi + 123。 Using LEA on values that aren't addresses / pointers?

【讨论】:

linux共享内存的控制释放

...块的相关信息。同时shmctl允许程序修改这些信息。该函数的第一个参数是一个共享内存块标识。要获取一个共享内存块的相关信息,则为该函数传递IPC_STAT作为第二个参数,同时传递一个指向一个structshmid_ds对象的指针作为第三... 查看详情

为啥“The Little Schemer”坚持 `cons` 的第二个参数必须是一个列表?

】为啥“TheLittleSchemer”坚持`cons`的第二个参数必须是一个列表?【英文标题】:Whydoes"TheLittleSchemer"insistthatthesecondargumentto`cons`mustbealist?为什么“TheLittleSchemer”坚持`cons`的第二个参数必须是一个列表?【发布时间】:2022-0... 查看详情

使用依赖注入时,如何修复“在前一个操作完成之前在此上下文中启动的第二个操作......”?

...时,如何修复“在前一个操作完成之前在此上下文中启动的第二个操作......”?【英文标题】:Howtofix\'Asecondoperationstartedonthiscontextbeforeapreviousoperationcompleted...\'whenworkingwithdependencyinjection?【发布时间】:2018-03-0519:54:33【问题描述... 查看详情

存储管理学习笔记

...,因为第二个程序在运行时会立即擦除掉在相同位置放置的第一个程序的数据这个时期,存储器模型就是物理内存,在只有一个操作系 查看详情

对 ITVF 的引用会引发“在前一个操作完成之前在此上下文上启动的第二个操作”异常

...的引用会引发“在前一个操作完成之前在此上下文上启动的第二个操作”异常【英文标题】:ReferencetoanITVFraisesa"secondoperationstartedonthiscontextbeforeapreviousoperationcompleted"exception【发布时间】:2018-10-2516:58:54【问题描述】:我... 查看详情

多个进程共享内存

...共享内存,可以用于进程通信,也可以用于线程通行。第一个参数是首地址第二个参数表示是否将其锁定为当前的进程内,FALSE表示不锁定。第三个是命名。在操作系统中,一个进程是不能读写另一个进程的内存的,他们的进程... 查看详情

observable里的常见操作符理解

...,代表数据源的是以字符串来相加的,如果传num,数据源的第一个数会与num的值相加,再做计算。reduce操作符,是把所有数据源通过计算输出一个值,第二个参数是输出总值跟其相加再输出。scan返回的一定是一个Observable对象,... 查看详情

逗号运算符返回参数列表中的第一个值而不是第二个值?

...115:17:27【问题描述】:MDN声称:逗号运算符计算它的两个操作数(从左到右)并返回第二个操作数的值。但是,当我尝试运行<script>alert(1,2);</script 查看详情

并发编程之happen-before原则

...e原则提供跨线程内存的可见性保证)原则:定义:1、如果一个操作happens-before另一个操作,那么第一个操作的结果对第二个可见,且第一个执行顺序在第二个之前。2、两个操作存在happens-before关系,并不意味着Java平台具体实现必... 查看详情

从零开始的操作系统

...创建自己的操作系统。我该怎么做呢?我知道我必须创建一个引导加载程序。但我从那里去哪里?我必须将它发送到另一个程序,但要做到这一点,该程序必须已经存在,并且我必须确切知道它在内存空间中的位置。任何提示/... 查看详情

applyBindings 的第二个参数是做啥用的?

】applyBindings的第二个参数是做啥用的?【英文标题】:What\'stheapplyBindings\'secondparameterusedfor?applyBindings的第二个参数是做什么用的?【发布时间】:2013-09-3004:17:32【问题描述】:我一直在寻找但找不到applyBindings()的文档。第二个... 查看详情

计算机操作系统-内存管理

...页(程序地址空间)和页框(物理内存空间)的映射表。一个虚拟地址分为页面号(16位地址是前4位)和存储偏移量。页面号的十进制数对应页表的索引,一个页表项最后一位表示是否存在于内存,前几位即为页框的前几位。2... 查看详情

操作系统内存管理

...个基本要求:执行指令必须在物理内存中,满足这一要求的第一种方法是整个进程放在内存中。动态载入能帮助减轻这一限制,但是它需要程序员特别小心地做一些额外的工作。指令必须都在物理内存内的这一限制,似乎是必须... 查看详情

第三章

...送入ds。 mov、add、sub指令   add、sub指令的操作数不能是段寄存器 常数作第二个操作数时,如果是最高位是16进制的a~f前面要加0,如movax,0a400h 在内存和寄存器之间传送字型数据时,高地址单元和高8位寄存器... 查看详情

没有第二个操作数的三元运算符[重复]

】没有第二个操作数的三元运算符[重复]【英文标题】:Ternaryoperatorwithoutsecondoperand[duplicate]【发布时间】:2016-04-1307:00:37【问题描述】:这是一个两方面的问题:一个是针对C的,一个是针对C++的。C和C++标准对以下三元(?:)运算符... 查看详情

Django 表单字段验证 - 如何判断操作是插入还是更新?

...ngo中执行此操作:在管理员中保存对象时,我还想根据我的第一个对象中的一个字段保存另一个不同类型的对象。为了做到这一点,我必须检查第二个对象是否已经存在,如果存在 查看详情

汇编语言指令的基本格式是啥

...语法;一、汇编语言语句的通用格式[名称[:]]指令码[第一操作数][,第二操作数];注释汇编语言的指令码的操作数的个数可以是0、1、2个;当操作数的个数为2的时候,语句还有两种不同的格式:Windows下Intel风格的汇编语言语句格式为:[名... 查看详情

在此上下文中启动了第二个操作

...述】:在我的控制器中,我在保存到DB的日期之后执行另一个Void函数。但有时它会显示此错误:第二个操作在前一个上下文之前开始异步操作完成。使用“等待”确保任何异步操作在调用另一个方法之前已经完成在这种情况下。... 查看详情