相关疑难解决方法(0)

如果只需要结果的低部分,那么可以使用哪个2的补码整数运算而不将输入中的高位置零?

在汇编编程中,想要从寄存器的低位计算某些东西是相当普遍的,这些位不能保证将其他位置零.在像C这样的高级语言中,你只需将输入转换为小尺寸,让编译器决定是否需要分别将每个输入的高位归零,或者是否可以在输出之后切断结果的高位.事实.

这是为x86-64的(又名AMD64),出于各种原因尤其常见1,其中的一些是存在于其它的ISA.

我将使用64位x86作为示例,但目的是询问/讨论2的补码和无符号二进制算法,因为所有现代CPU都使用它.(注意,C和C++不保证两个补码4,并且有符号溢出是未定义的行为.)

作为示例,考虑一个可以编译为LEA指令2的简单函数.(在X86-64 SysV的(Linux)的ABI 3,前两个函数参数是rdirsi,与在返回rax. int是一个32位的类型.)

; int intfunc(int a, int b) { return a + b*4 + 3; }
intfunc:
    lea  eax,  [edi + esi*4 + 3]  ; the obvious choice, but gcc can do better
    ret
Run Code Online (Sandbox Code Playgroud)

gcc知道即使是负有符号整数,加法也只是从右到左,所以输入的高位不会影响进入的内容eax.因此,它保存了一个指令字节并使用 lea eax, [rdi + rsi*4 + 3]

哪些其他操作具有结果低位的这种属性而不依赖于输入的高位?

为什么它有效?



脚注

1为什么x86-64频繁出现这种情况:x86-64有可变长度指令,其中额外的前缀字节改变了操作数大小(从32到64或16),因此在指令中通常可以保存一个字节.以相同的速度执行.当写入低8b或16b的寄存器(或稍后读取完整寄存器(Intel pre-IvB)时的失速)时,它也具有错误依赖性(AMD/P4/Silvermont):由于历史原因, …

binary x86 assembly integer twos-complement

12
推荐指数
1
解决办法
928
查看次数

为什么汇编指令在"lea"指令中包含乘法?

我正在开发一个非常低级别的应用程序,其中性能至关重要.

在调查生成的程序集时,我注意到以下指令:

lea eax,[edx*8+8]
Run Code Online (Sandbox Code Playgroud)

我习惯在使用内存引用时看到添加内容(例如[edx + 4]),但这是我第一次看到乘法.

  • 这是否意味着x86处理器可以在lea指令中执行简单的乘法运算?
  • 这种乘法是否会影响执行指令所需的周期数?
  • 乘法是否限制为2的幂(我会假设是这种情况)?

提前致谢.

x86 assembly disassembly machine-instruction

11
推荐指数
3
解决办法
5067
查看次数

Elf的.rel.text部分中R_386_32/R_386_PC32的含义

要了解重定位的概念,我写了一个简单的chk.c程序如下:

  1 #include<stdio.h>
  2 main(){
  3         int x,y,sum;
  4         x = 3;
  5         y = 4;
  6         sum = x + y;
  7         printf("sum = %d\n",sum);
  8 }
Run Code Online (Sandbox Code Playgroud)

它的等效汇编代码,使用"objdump -d chk.o"是:

00000000 <main>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 e4 f0                and    $0xfffffff0,%esp
   6:   83 ec 20                sub    $0x20,%esp
   9:   c7 44 24 1c 03 00 00    movl   $0x3,0x1c(%esp)
  10:   00 
  11:   c7 44 24 18 04 00 00    movl   $0x4,0x18(%esp)
  18:   00 
  19:   8b …
Run Code Online (Sandbox Code Playgroud)

c linux x86 assembly

11
推荐指数
2
解决办法
4058
查看次数

麻烦理解汇编命令"加载有效地址"

可能重复:
LEA指令的目的是什么?
LEA指令?

所以我正在为类进行二进制炸弹分配(它有一堆阶段,你必须逐步执行程序的汇编代码并找到密码来解码"炸弹").

我无法完成当前阶段,因为我不理解lea命令.我已经读过它通常用于算术,但我只是不明白它是如何做到的.

我正在看的命令是

lea -0x18(%ebp), %ebx
lea -0x8(%ebp), %esi
Run Code Online (Sandbox Code Playgroud)

接下来是

mov -0x4 (%ebx), %eax
add -0x8(%ebx), %eax
Run Code Online (Sandbox Code Playgroud)

在下一行eax和ebx进行比较,如果它们等于程序继续,否则炸弹爆炸.

我已经足够了解这个阶段知道它想要6个数字,前两个是0和1.之后它做了一些操作来确定序列的其余部分是否正确(我假设lea命令是什么我需要解码才能找到下一个数字).

现在我找不到的是-0x18特别指的是什么.什么是负号呢?它表示减法吗?它在ebp之前看起来是18个字节吗?

感谢您的帮助.

x86 assembly

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

C++内联汇编(英特尔编译器):LEA和MOV在Windows和Linux中表现不同

我正在转换一个巨大的Windows DLL以在Windows和Linux上工作.dll有很多用于视频操作的汇编(和SS2指令).

现在,使用Windows上的Intel ComposerXE-2011和Linux上的Intel ComposerXE-2013 SP1中包含的英特尔编译器,可以在Windows和Linux上编译代码.

但是,在尝试调用函数指针时,执行会在Linux中崩溃.我在gdb中跟踪代码,实际上函数指针并没有指向所需的函数(而在Windows中则没有).几乎所有其他工作正常.

这是代码序列:

...
mov    rdi, this
lea    rdx, [rdi].m_sSomeStruct
...
lea    rax, FUNCTION_NAME                # if replaced by 'mov', works in Linux but crashes in Windows
mov    [rdx].m_pfnFunction, rax
...
call   [rdx].m_pfnFunction               # crash in Linux
Run Code Online (Sandbox Code Playgroud)

哪里:

1)'this'有一个struct成员m_sSomeStruct.

2)m_sSomeStruct有一个成员m_pfnFunction,它是一个指向函数的指针.

3)FUNCTION_NAME是同一编译单元中的自由函数.

4)所有这些纯组装函数都声明为裸.

5)64位环境.

让我最困惑的是,如果我用'mov'指令替换应该将函数地址加载到rax中的'lea'指令,它在Linux上工作正常但在Windows上崩溃.我在Visual Studio和gdb中都跟踪了代码,显然在Windows"lea"中给出了正确的函数地址,而在Linux'mov'中则是这样.

我试着查看英特尔组装参考,但没有找到太多帮助我(除非我没有找对地方).

任何帮助表示赞赏.谢谢!


编辑更多详情:

1)我尝试使用方括号

lea    rax, [FUNCTION_NAME]
Run Code Online (Sandbox Code Playgroud)

但这并未改变Windows和Linux中的行为.

2)我在gdb和Windows中查看了反汇编程序,似乎都给出了我实际编写的相同指令.更糟糕的是,我尝试将两个lea/ mov一个接一个地放在一起,当我在gdb的反汇编中查看它们时,在#符号之后的指令后打印的地址(我假设是将要存储的地址)在寄存器中)实际上是相同的,并且不是函数的正确地址.

它在gdb反汇编程序中看起来像这样

lea  0xOffset1(%rip), %rax   # 0xSomeAddress
mov  0xOffset2(%rip), %rax   # 0xSomeAddress
Run Code Online (Sandbox Code Playgroud)

其中两个(SomeAddress)是相同的,并且两个偏移都是由lea和mov指令之间的相同差异关闭的,但不知何故,当我在每次执行后检查寄存器的内容时​​,mov似乎放入了正确的值! !

3)成员变量m_pfnFunction的类型为LOAD_FUNCTION,定义为

typedef …
Run Code Online (Sandbox Code Playgroud)

c c++ linux assembly intel

10
推荐指数
1
解决办法
675
查看次数

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

x86架构中的"EU"是什么?(计算有效地址?)

我在某处读到x86指令中的有效地址(如LEA指令中)由"EU"计算.什么是欧盟?计算有效地址究竟涉及什么?

我只学习了MC68k指令集(UC博尔德首先教这个),我找不到一个好的x86网页,通过网络搜索.

x86 assembly cpu-architecture

7
推荐指数
2
解决办法
854
查看次数

方法调用之前的lea指令是什么?

在查看我的反汇编代码时,我看到了很多以下内容:

00B442E9  push        4  
00B442EB  push        3  
00B442ED  lea         ecx,[ebp-24h]  
00B442F0  call        Foo::Bar (0B41127h)  
Run Code Online (Sandbox Code Playgroud)

我理解在通话之前推送参数,但是lea这里做了什么?

c++ assembly visual-c++

7
推荐指数
1
解决办法
667
查看次数

lea汇编指令

我只是想确保我正在读这个:

movl 12(%ebp), %edx
leal (%edx, %edx, 4), %eax
Run Code Online (Sandbox Code Playgroud)

我读第一行为:edx = [epb + 12],第二行为:eax = edx + edx*4

任何人都可以澄清一下吗?

另外,如果我有以下两行怎么办:

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

执行第二行后,eax寄存器会被覆盖吗?

并将eax = edx + edx*4地址乘以4?或者地址的内容由4?

x86 assembly att addressing-mode

7
推荐指数
2
解决办法
2万
查看次数

这段 x86-64 代码中的 lea 有什么作用?

这是函数的前四行。我知道前两行在堆栈中创建一个新框架,基本上是“设置”行。lea 指令有什么作用?

40148e: 48 83 ec 18    sub    $0x18,%rsp
401492: 48 89 f2       mov    %rsi,%rdx
401495: 48 8d 4e 04    lea    0x4(%rsi),%rcx
401499: 48 8d 46 14    lea    0x14(%rsi),%rax
Run Code Online (Sandbox Code Playgroud)

assembly x86-64

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