如果我要用汇编语言编写程序,此HelloWorld汇编代码的哪些部分必不可少? [英] What parts of this HelloWorld assembly code are essential if I were to write the program in assembly?

查看:192
本文介绍了如果我要用汇编语言编写程序,此HelloWorld汇编代码的哪些部分必不可少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简短的hello world程序:

I have this short hello world program:

#include <stdio.h>

static const char* msg = "Hello world";

int main(){
    printf("%s\n", msg);
    return 0;
}

我使用gcc将其编译为以下汇编代码:

I compiled it into the following assembly code with gcc:

    .file   "hello_world.c"
    .section    .rodata
.LC0:
    .string "Hello world"
    .data
    .align 4
    .type   msg, @object
    .size   msg, 4
msg:
    .long   .LC0
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushl   %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $16, %esp
    movl    msg, %eax
    movl    %eax, (%esp)
    call    puts
    movl    $0, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
    .section    .note.GNU-stack,"",@progbits

我的问题是:如果我要用汇编语言编写该程序(而不是用C编写然后编译为汇编语言),那么此代码的所有部分是否必不可少?我了解组装说明,但是有些部分我不理解.例如,我不知道什么是.cfi *,而且我想知道是否需要包括此文件才能在程序集中编写该程序.

My question is: are all parts of this code essential if I were to write this program in assembly (instead of writing it in C and then compiling to assembly)? I understand the assembly instructions but there are certain pieces I don't understand. For instance, I don't know what .cfi* is, and I'm wondering if I would need to include this to write this program in assembly.

推荐答案

在看起来似乎可以运行的平台上的绝对最低要求是

The absolute bare minimum that will work on the platform that this appears to be, is

        .globl main
main:
        pushl   $.LC0
        call    puts
        addl    $4, %esp
        xorl    %eax, %eax
        ret
.LC0:
        .string "Hello world"

但是,这违反了许多 ABI 的要求.符合ABI计划的最低要求是

But this breaks a number of ABI requirements. The minimum for an ABI-compliant program is

        .globl  main
        .type   main, @function
main:
        subl    $24, %esp
        pushl   $.LC0
        call    puts
        xorl    %eax, %eax
        addl    $28, %esp
        ret
        .size main, .-main
        .section .rodata
.LC0:
        .string "Hello world"

目标文件中的所有其他内容是编译器未尽可能严格地优化代码,或者是可选批注将被写入目标文件.

Everything else in your object file is either the compiler not optimizing the code down as tightly as possible, or optional annotations to be written to the object file.

.cfi_*指令尤其是可选注释.当且仅当抛出C ++异常时函数可能在调用堆栈上时,它们才是必要的,但是对于您可能要从中提取的任何程序,它们都是有用的.堆栈跟踪.如果您打算用汇编语言手工编写非平凡的代码,那么值得学习如何编写它们.不幸的是,它们的文献很少.我目前找不到我认为值得链接的任何内容.

The .cfi_* directives, in particular, are optional annotations. They are necessary if and only if the function might be on the call stack when a C++ exception is thrown, but they are useful in any program from which you might want to extract a stack trace. If you are going to write nontrivial code by hand in assembly language, it will probably be worth learning how to write them. Unfortunately, they are very poorly documented; I am not currently finding anything that I think is worth linking to.

.section    .note.GNU-stack,"",@progbits

了解是否要手工编写汇编语言也很重要;它是另一个可选的注释,但是却是一个有价值的注释,因为它的意思是此目标文件中的任何内容都不需要堆栈是可执行的".如果程序中的所有目标文件都带有此批注,则内核将使堆栈无法执行,从而在某种程度上提高了安全性.

is also important to know about if you are writing assembly language by hand; it is another optional annotation, but a valuable one, because what it means is "nothing in this object file requires the stack to be executable." If all the object files in a program have this annotation, the kernel won't make the stack executable, which improves security a little bit.

((为了表明您 do 需要堆栈是可执行的,请放置"x"而不是"".如果您使用其嵌套函数"扩展名,GCC可能会这样做.(Don不这样做.)

(To indicate that you do need the stack to be executable, you put "x" instead of "". GCC may do this if you use its "nested function" extension. (Don't do that.))

可能值得一提的是,在GCC和GNU binutils使用的"AT& T"汇编语法(默认情况下)中,有以下三种类型的行: 上面带有单个标记(以冒号结尾)的是标签. (我不记得在标签中可以显示哪些字符的规则.)一行 first 标记以点开头,而 not 以冒号结尾的行是对汇编程序的某种指令.其他就是汇编指令.

It is probably worth mentioning that in the "AT&T" assembly syntax used (by default) by GCC and GNU binutils, there are three kinds of lines: A line with a single token on it, ending in a colon, is a label. (I don't remember the rules for what characters can appear in labels.) A line whose first token begins with a dot, and does not end in a colon, is some kind of directive to the assembler. Anything else is an assembly instruction.

这篇关于如果我要用汇编语言编写程序,此HelloWorld汇编代码的哪些部分必不可少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆