这个汇编代码的解释是什么?

nik*_*agi 0 linux x86 assembly nasm

section .text
    global _start       ;must be declared for using gcc
_start:                     ;tell linker entry point
    mov edx, len    ;message length
    mov ecx, msg    ;message to write
    mov ebx, 1      ;file descriptor (stdout)
    mov eax, 4      ;system call number (sys_write)
    int 0x80        ;call kernel
    mov eax, 1      ;system call number (sys_exit)
    int 0x80        ;call kernel

section .data

msg db  'Hello, world!',0xa ;our dear string
len equ $ - msg         ;length of our dear string
Run Code Online (Sandbox Code Playgroud)

这是打印"Hello,World!"的基本汇编代码.屏幕上.现在我想问一下这段代码是如何在幕后工作的.就像所有这些指令的需要一样

nasm -felf -g -Fdwarf hello.asm
gcc -g -m32 -nostdlib -static -o hello hello.o
./hello
Run Code Online (Sandbox Code Playgroud)

只是为了打印"Hello,World!" 和声明

_start:                     ;tell linker entry point
        mov edx, len    ;message length
        mov ecx, msg    ;message to write
        mov ebx, 1      ;file descriptor (stdout)
        mov eax, 4      ;system call number (sys_write)
        int 0x80        ;call kernel
        mov eax, 1      ;system call number (sys_exit)
        int 0x80        ;call kernel
Run Code Online (Sandbox Code Playgroud)

以上!它是主要功能吗?

和声明

_start:
Run Code Online (Sandbox Code Playgroud)

为什么要使用呢?你能不能给我一个关于这个程序基本工作的深刻解释.

fuz*_*fuz 9

在机器代码中,没有功能.至少,处理器对功能一无所知.程序员可以根据自己的喜好构建代码._start是一种称为符号的东西,它只是程序中某个位置的名称.符号用于指代您还不知道地址的位置.它们在链接期间得到解决.该符号_start用作入口点(参见本答案),操作系统跳转到该入口点以启动程序.除非您通过其他方式指定入口点,否则每个程序都必须包含_start.程序使用的其他符号msg,由链接器解析为字符串Hello, world!所在的地址,len长度为msg.

该程序的其余部分执行以下操作:

  1. 设置系统调用的寄存器write(1, msg, len).write系统调用号4存储在eax操作系统中,让操作系统知道您想要系统调用4.此系统调用将数据写入文件.提供的文件描述符编号为1,表示标准输出.
  2. 使用执行系统调用int $0x80.该指令会中断您的程序,操作系统会选择该程序并执行存储其编号的功能eax.
  3. 设置系统调用的寄存器_exit(?).它的系统呼叫号码是1 eax.遗憾的是,代码忘记设置参数_exit,该参数应该为0表示成功.相反,ebx使用之前的任何东西代替,似乎是1.
  4. 使用执行系统调用int $0x80.因为_exit结束程序,它不会返回.你的程序在此结束.

该指令db告诉汇编器将以下数据放入我们当前所在的程序中.这会将字符串Hello, world!后跟换行符放入程序中,这样我们就可以告诉write系统调用写入该字符串.

该行len equ $ - msg告诉汇编程序,而不是(我们当前所处的位置)和len之间的差异.这是定义的,所以我们可以传递我们想要打印的文本多长时间.$msgwrite

;程序中的分号()之后的所有内容都是编译器忽略的注释.