当前位置: 首页 > 知识库问答 >
问题:

程序集移动指令似乎无用[重复]

朱皓
2023-03-14

我在学组装。我拆解了一个简单的C程序,并用GDB进行了调试。但我注意到的一件事是,值的移动非常频繁。

   0x0000555555555231 <+0>:     push   rbp
   0x0000555555555232 <+1>:     mov    rbp,rsp
   0x0000555555555235 <+4>:     sub    rsp,0x20

   0x0000555555555239 <+8>:     mov    QWORD PTR [rbp-0x18],rdi
   0x000055555555523d <+12>:    mov    QWORD PTR [rbp-0x20],rsi
   0x0000555555555241 <+16>:    mov    rax,QWORD PTR [rbp-0x18]
   0x0000555555555245 <+20>:    mov    rdi,rax
   0x0000555555555248 <+23>:    call   0x5555555551d9 <get_file_size>

RDI的值在rbp-0x18(<+8>)处移动到堆栈,RSI的值在rbp-0x20(+12)处移动到堆栈。然后,rbp-0x18处的值被移动到rax(+16),该值将再次被移动到rdi(+20)。为什么要这样做?为什么不直接使用rdi,或者至少通过rax(<+16>)直接将rbp-0x18移动到rdi?这可以节省+20时的指令

共有1个答案

虞祯
2023-03-14

如果您想学习汇编程序,那么没有启用任何优化的编译没有多大意义。

这里有一个优化如何更改生成的代码的示例。

https://godbolt.org/z/ybdlrz

char *foo(char *dest, const char *src, size_t len)
{
    char *savedDest = dest;
    size_t index = 0;
    if(len)
    {
        while(--len && (dest[index] = src[index]));
        index++;
        *dest = 0;
    }
    return savedDest;
}
foo:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-24], rdi
        mov     QWORD PTR [rbp-32], rsi
        mov     QWORD PTR [rbp-40], rdx
        mov     rax, QWORD PTR [rbp-24]
        mov     QWORD PTR [rbp-8], rax
        mov     QWORD PTR [rbp-16], 0
        cmp     QWORD PTR [rbp-40], 0
        je      .L2
.L4:
        sub     QWORD PTR [rbp-40], 1
        cmp     QWORD PTR [rbp-40], 0
        je      .L3
        mov     rdx, QWORD PTR [rbp-32]
        mov     rax, QWORD PTR [rbp-16]
        add     rdx, rax
        mov     rcx, QWORD PTR [rbp-24]
        mov     rax, QWORD PTR [rbp-16]
        add     rax, rcx
        movzx   edx, BYTE PTR [rdx]
        mov     BYTE PTR [rax], dl
        movzx   eax, BYTE PTR [rax]
        test    al, al
        jne     .L4
.L3:
        add     QWORD PTR [rbp-16], 1
        mov     rax, QWORD PTR [rbp-24]
        mov     BYTE PTR [rax], 0
.L2:
        mov     rax, QWORD PTR [rbp-8]
        pop     rbp
        ret
foo:
        mov     rax, rdi
        test    rdx, rdx
        je      .L2
.L4:
        dec     rdx
        je      .L3
        mov     cl, BYTE PTR [rsi]
        mov     BYTE PTR [rax], cl
        test    cl, cl
        jne     .L4
.L3:
        mov     BYTE PTR [rax], 0
.L2:
        ret
 类似资料:
  • 程序转移指令 1>无条件转移指令 (长转移) JMP 无条件转移指令 CALL 过程调用 RET/RETF过程返回. 2>条件转移指令 (短转移,-128到+127的距离内) ( 当且仅当(SF XOR OF)=1时,OP1循环控制指令(短转移) LOOP CX不为零时循环. LOOPE/LOOPZ CX不为零且标志Z=1时循环. LOOPNE/LOOPNZ CX不为零且标志Z=0时循环. JCX

  • 我有一个适用于Android和iOS的应用程序。有很多复杂的SQL查询,所以我有一个c层来生成查询,这样就可以在android和ios上使用这种逻辑。 一切都很好,但我注意到在Android系统上,第二类由于某种原因不适合我。 我有一个项目列表,我想按日期排序,然后第二次按标题排序。在iOS上,这很好,在Android系统上,虽然按日期排序,标题不是第二次按标题排序。 查询和数据库文件在两个平台上

  • 下面是我的c函数: 如果str[i]=='a',则将设置zflag,je.L5将接受分支。如果str[i]!='a',则将清除zflag。je.L5不会拿树枝。 为什么编译器在cmpb指令后生成两行额外的代码?

  • 问题内容: 这个问题已经在这里有了答案 : 在排序时访问列表 (2个答案) 6年前关闭。 我想就地对列表进行排序,并尝试在排序过程中(功能内)使用列表本身。我发现列表本身似乎是空的。 所以我尝试了: 并得到 有什么解释吗? 问题答案: 从源代码: 并从Mutable Sequence Types文档中 : CPython实现细节 :在对列表进行排序时,尝试使列表变异甚至检查的效果是不确定的。Pyt

  • 我正在创建一个应用程序,用户在其中输入 7-10 个数值。然后,条目用于一个相当分层的公式,该公式向用户返回结果。两个值给我带来了麻烦,并产生了一个我无法弄清楚的数字。 从微调器中选择一个条目,因为只有4种可能的选择: 此选项不仅用于等式,还用于确定是否需要额外的信息。 获得IHCValue: 如果用户从此下拉列表中选择“2”,则下一个活动将要求 ,也用于等式的一部分: 获取FISHEntry:

  • 我正在遵循斯普林特启动的15分钟指南(gs-关系-数据-访问) 因此,该指南使用H2数据库。现在我通过在运行时提供JAR来改变这一点,以使用DB2。 改良build.gradle 现在应用程序失败了,抱怨没有找到JDBCTemplateBean定义或类似的东西。 所以现在我进一步修改了build.gradle注释掉sping-jdbc,并使用sping-boo-starter-jdbc 现在,应用