为什么 C 编译器在 RET 指令后生成 NOP?

ASL*_*LOP 2 c macos assembly

在 OSX 64 位上,编译一个像这样的虚拟 C 程序:

#include <stdio.h>

void foo1() {
}

void foo2() {
}

int main() {
        printf("Helloooo!\n");
        foo1();
        foo2();
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

生成以下 ASM 代码(使用 otool 反汇编二进制文件):

(__TEXT,__text) section
_foo1:
0000000100000f10    55                  pushq   %rbp
0000000100000f11    4889e5              movq    %rsp, %rbp
0000000100000f14    897dfc              movl    %edi, -0x4(%rbp)
0000000100000f17    5d                  popq    %rbp
0000000100000f18    c3                  retq
0000000100000f19    0f1f8000000000      nopl    (%rax)
_foo2:
0000000100000f20    55                  pushq   %rbp
0000000100000f21    4889e5              movq    %rsp, %rbp
0000000100000f24    5d                  popq    %rbp
0000000100000f25    c3                  retq
0000000100000f26    662e0f1f840000000000    nopw    %cs:(%rax,%rax)
_main:
0000000100000f30    55                  pushq   %rbp
0000000100000f31    4889e5              movq    %rsp, %rbp
0000000100000f34    4883ec10            subq    $0x10, %rsp
0000000100000f38    488d3d4b000000      leaq    0x4b(%rip), %rdi        ## literal pool for: "Helloooo!\n"
0000000100000f3f    c745fc00000000      movl    $0x0, -0x4(%rbp)
0000000100000f46    b000                movb    $0x0, %al
0000000100000f48    e81b000000          callq   0x100000f68             ## symbol stub for: _printf
0000000100000f4d    bf06000000          movl    $0x6, %edi
0000000100000f52    8945f8              movl    %eax, -0x8(%rbp)
0000000100000f55    e8b6ffffff          callq   _foo1
0000000100000f5a    e8c1ffffff          callq   _foo2
0000000100000f5f    31c0                xorl    %eax, %eax
0000000100000f61    4883c410            addq    $0x10, %rsp
0000000100000f65    5d                  popq    %rbp
0000000100000f66    c3                  retq
Run Code Online (Sandbox Code Playgroud)

在函数 foo1() 和 foo2() 的“ret”之后发现的“nop”指令是什么?当然,它们从未被执行,因为“ret”指令从函数调用返回。这是任何一种填充还是有不同的含义?

Enk*_*lli 5

来自x86 处理器汇编语言,Kip R. Irvine

您可以编写的最安全(也是最无用)的指令称为 NOP(无操作)。它占用 1 个字节的程序存储空间,并且不做任何工作。编译器和汇编器有时使用来将代码与偶地址边界对齐

00000000 66 8B C3 mov ax,bx  
00000003 90 nop ; align next instruction  
00000004 8B D1 mov edx,ecx  
Run Code Online (Sandbox Code Playgroud)