【发布时间】:2017-07-12 08:20:04
【问题描述】:
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
这是一个基本的 32 位 x86 Linux 汇编代码,用于打印“Hello, World!”在屏幕上(标准输出)。构建 + 运行它
nasm -felf -g -Fdwarf hello.asm
gcc -g -m32 -nostdlib -static -o hello hello.o
./hello
(编者注:或gdb ./hello 进行调试/单步调试。这就是我们使用nasm -g -Fdwarf 和gcc -g 的原因。或者在GDB 中使用layout reg 进行不依赖于调试的反汇编+注册视图符号。见底部https://stackoverflow.com/tags/x86/info)
现在我想问一下这段代码是如何在幕后工作的。就像所有这些说明需要什么
_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
只是为了打印“Hello, World!”和声明
_start:
以上!是main函数吗?
和声明
int 0x80
为什么要使用它?你们能不能给我详细解释一下这个程序的基本工作原理。
【问题讨论】:
-
您似乎缺乏 Linux 的基础知识,或者一般来说,缺乏汇编编程。一本书或在线教程可能更合适:-) 这里唯一的汇编特定方面是权限转移(系统调用),现在已经过时的 32 位,
int 0x80。程序的其余部分只是设置作为程序员的任何编程语言所期望的参数。 -
“起初神创造天地”……我们应该从哪里开始呢? @MargaretBloom 完全正确,请尝试寻找一个好的教程
-
请给我一些建议?
-
“就像所有这些指令只需要打印“Hello, World!” ...实际上这部分几乎什么都不做,你好世界的肉在这种情况下,打印指令隐藏在操作系统中。如果这是一些旧的 8 位计算机示例,通过直接将值写入视频 RAM 并设置视频芯片来显示它们,在屏幕上创建“Hello, World”,那么代码将涉及更多指令和更复杂的逻辑,此外,您还需要每个字母的“字体”像素数据等......这就像“嘿操作系统,为我打印 Hello world。”工作“努力”。跨度>
-
相关:Hello, world in assembly language with Linux system calls? 使用 32 位 int 0x80 系统调用获得完整注释的“Hello World”。还 another answer 使用 libc 中的
puts而不是直接系统调用。