相关疑难解决方法(0)

汇编为什么是“lea eax, [eax + eax*const]; shl eax, eax, const;” 根据 gcc -O2,组合速度比“imul eax, eax, const”更快?

我正在使用 godbolt 来组装以下程序:

\n
#include <stdio.h>\nvolatile int a = 5;\nvolatile int res = 0;\nint main() {\n    res = a * 36;\n    return 1;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果我使用-Os优化,生成的代码很自然:

\n
mov     eax, DWORD PTR a[rip]\nimul    eax, eax, 36\nmov     DWORD PTR res[rip], eax\n
Run Code Online (Sandbox Code Playgroud)\n

但如果我使用-O2,生成的代码是这样的:

\n
mov     eax, DWORD PTR a[rip]\nlea     eax, [rax+rax*8]\nsal     eax, 2\nmov     DWORD PTR res[rip], eax\n
Run Code Online (Sandbox Code Playgroud)\n

因此,它不是乘以 5*36,而是执行 5 -> 5+5*8=45 -> 45*4 = 180。我认为这是因为 1 imul 比 1 lea + 1 左移慢。

\n

但在 lea 指令中,需要计算rax+rax*8,其中包含 1 个加法 …

c optimization assembly x86-64 cpu-architecture

6
推荐指数
1
解决办法
711
查看次数

x86组装中的LEA

我正在学习x86汇编,并且在lea指令上遇到了一些麻烦。

 0x080486f7 <+21>:  lea    eax,[esp+0x18]
Run Code Online (Sandbox Code Playgroud)

谁能解释这行发生了什么?以我的理解,它将值取为[esp + 0x18]并将其解释为地址,然后将整数地址的值放入eax。

x86 assembly

5
推荐指数
2
解决办法
2213
查看次数

程序集lea指令int*q = p ++和int c = a ++

为了加深对"(*p)++"如何工作的印象,我写了一些测试代码,如:

int main()
{
  int  a = 3;
  int *p = &a;
  int b = (*p)++;
  int *q = p++;
  int c = a++;
  int d = c++;
  printf("a = %d, b = %d, c = %d, d = %d, p = %#x, q = %#x\n",a, b, c, d, p, q);
}
Run Code Online (Sandbox Code Playgroud)

输出为:a = 5,b = 3,c = 5,d = 4,p = 0xc6dc3490,q = 0xc6dc348c

但我的问题是关于装配(代码是订单而不是关闭和开启):

main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 48

;int a = 3 : …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly

5
推荐指数
2
解决办法
491
查看次数

LEA和几个指令如何工作?

我不完全理解前两行的含义,以及最后两行的区别.

LDS SI,[BX]
LES DI,[BX]
LEA DI,5000h 
MOV DI,5000h
Run Code Online (Sandbox Code Playgroud)

我认为LEA在DI中加载5000h,MOV在DI中加载5000h的内容.我对吗??

x86 assembly

4
推荐指数
1
解决办法
1607
查看次数

引用内存位置的内容.(x86寻址模式)

我有一个内存位置,其中包含一个我想要与另一个角色进行比较的角色(并且它不在堆栈的顶部,所以我不能只是pop它).如何引用内存位置的内容以便进行比较?

基本上我如何在语法上做到这一点.

x86 assembly masm addressing-mode

4
推荐指数
1
解决办法
6687
查看次数

在检索地址方面,MOV和LEA之间有什么区别

当我使用它们获取地址时,mov和lea之间究竟有什么区别?

假设我有一个程序从第5个字符开始打印出一个字符串,其代码如下所示:

section .text
    global _start
_start:
    mov edx, 0x06  ;the length of msg from its 5th char to the last is 6.
    lea ecx, [msg + 4]
    mov ebx, 1
    mov eax, 4
    int 0x80

section .data
msg db '1234567890'
Run Code Online (Sandbox Code Playgroud)

然后,如果我换lea ecx, [msg + 4]mov ecx, msg + 4,将它运行不同?

我试过两个,输出看起来是一样的.但是,我从这个链接中读到,LEA指令的目的是什么?,在第一个答案的评论部分,似乎有人声称有类似mov ecx, msg + 4无效的东西,但我没有看到它.有人能帮助我理解这个吗?提前致谢!

x86 assembly nasm

4
推荐指数
1
解决办法
1236
查看次数

在不是地址/指针的值上使用LEA?

我试图了解地址计算指令的工作原理,尤其是leaq命令.然后当我看到leaq用于进行算术运算的例子时,我感到困惑.例如,以下C代码,

long m12(long x) {
return x*12;
}
Run Code Online (Sandbox Code Playgroud)

在组装中

leaq (%rdi, %rdi, 2), %rax
salq $2, $rax
Run Code Online (Sandbox Code Playgroud)

如果我的理解是正确的,那么leaq应该移动任何(%rdi, %rdi, 2)应该2*%rdi+%rdi评估的地址%rax.我感到困惑的是,因为值x存储%rdi在内,这只是内存地址,为什么%rdi乘以3然后左移这个内存地址 2等于x乘以12?是不是当我们%rdi用3时,我们跳到另一个没有值x的内存地址?

c x86 assembly memory-address

4
推荐指数
2
解决办法
4927
查看次数

装配leal和movl的区别

leal(%eax,%ecx,4), %edx
Run Code Online (Sandbox Code Playgroud)

当我从我的计算机系统书中读到时,如果$ eax包含x值并且%ecx包含y,那么上面的意思是x + 4y放入%edx.

如果是的话

movl(%eax,%ecx,4), %edx
Run Code Online (Sandbox Code Playgroud)

那么上面的leal表达是不是同一个?

据我所知,leal创建了可以引用的地址,而不是像movl那样自己引用,但是

当我看到leal(%eax,%ecx,4), %edxequals x+4y进入edx注册时,那么t it mean that it 'referenced'%eax and%ecx`和提取值x和y用于计算?

  • 不是吗"()"的意思是'引用'??

x86 assembly att

3
推荐指数
1
解决办法
1万
查看次数

lea指令如何获取操作数的地址?

这是如何工作的?我知道lea与使用add/mov指令相比是有效的,因为它不通过ALU或设置任何标志.那么lea如何得到它的地址呢?是什么让它比添加/ mov更好?

x86 assembly

3
推荐指数
1
解决办法
403
查看次数

MUL/DIV指令与MOV和SHL/SHR(Pentium Pro)

你为什么要用:

MOV EAX, 22 
SHL EAX, 2
Run Code Online (Sandbox Code Playgroud)

...乘以4而不是仅仅使用MUL指令?
我知道这也可以用SHR而不是DIV.

这样做有什么好处?
你也可以用奇数做这个或者它只能是偶数吗?

x86 assembly opcodes

3
推荐指数
1
解决办法
1569
查看次数