汇编HelloWorld程序

一、环境介绍
本系列笔记的所有代码均基于 ubuntu22 5.19.0-38-generic + Intel x86_64 环境验证。

二、C码编译为汇编
1、源码

int main(int argc, char *argv[])
{
    write(1, "Hello World\n", 13);
    return 0;
}

2、编译
1)只带-S参数:gcc -S hello.c: 会产生很多当前不关注的信息,导致理解困难,放弃。
2)关闭一些默认的选项后编译运行:

$ gcc -fno-stack-protector -fomit-frame-pointer -fno-asynchronous-unwind-tables -fcf-protection=none  -S hello.c
$ gcc hello.s
$ ./a.out
Hello World

编译选项解释:

  • -fno-stack-protector:去掉 stack 保护,stack protector 用于检查 stack 是否被踩。
  • -fomit-frame-pointer:不用 fp 寄存器 rbp/ebp,直接用 stack 寄存器 rsp/esp 就好了。
  • -fno-asynchronous-unwind-tables:消除 .eh_frame section等不关注的信息。
  • -fcf-protection=none: 消除 endbr64 指令和其他一些不关注的信息。
    另外: -mmanual-endbr 选项仅消除 endbr64 指令。

三、编译输出的汇编代码
1、原始的hello.s

    .file   "hello.c"
    .text
    .section    .rodata
.LC0:
    .string "Hello World\n"
    .text
    .globl  main
    .type   main, @function
main:
    subq    $24, %rsp
    movl    %edi, 12(%rsp)
    movq    %rsi, (%rsp)
    movl    $13, %edx
    leaq    .LC0(%rip), %rax
    movq    %rax, %rsi
    movl    $1, %edi
    movl    $0, %eax
    call    write@PLT
    movl    $0, %eax
    addq    $24, %rsp
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0"
    .section    .note.GNU-stack,"",@progbits

2、手动删除不关注的代码后的hello.s
将.LC0 修改为msg

.section        .rodata
msg:
        .string "Hello World\n"
.text
        .globl  main
main:
        subq    $24, %rsp
        movl    %edi, 12(%rsp)
        movq    %rsi, (%rsp)
        movl    $13, %edx
        leaq    msg(%rip), %rax
        movq    %rax, %rsi
        movl    $1, %edi
        movl    $0, %eax
        call    write@PLT
        movl    $0, %eax
        addq    $24, %rsp
        ret
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容