Lettle
Lettle
发布于 2023-09-08 / 2 阅读 / 0 评论 / 0 点赞

x86汇编学习

1.输出Hello world

本次实验在Linux环境中进行。

为了在汇编中构建有用的程序,我们需要使用内核提供的 Linux 系统调用。这些系统调用是操作系统中内置的库,用于提供一些功能,比如从键盘读取输入和将输出写入屏幕等等。

当你调用系统调用时,内核将立即暂停你程序的执行。然后,它将通知必要的驱动程序,以在硬件上执行您请求的任务,然后将控制权返回给你的程序。

首先,我们在 .data 段中创建一个变量 msg ,并将要输出的字符串分配给它,在本例中为 "Hello world" 。在 .text 段,我们通过向内核提供一个全局标签 _start 来指示程序入口点,从而告诉内核从哪里开始执行。

我们使用系统调用 sys_write 将信息输出到控制台窗口。此函数在 Linux 系统调用表中指定为opcode 4。在请求执行任务的软件中断之前,该函数还接受 3 个参数,这些参数依次加载到edx,ecx,ebx中。

参数传递如下:

  • edx 置为字符串的长度(以字节为单位)

  • ecx 置为 .data 节中创建的变量的地址。

  • ebx 置为目的文件(在本例中为标准输出 stdout)。

使用以下命令编译、链接和运行程序。

编写出如下代码

; Hello, world!
; 文件名:helloworld.asm
; 编译:nasm -f elf helloworld.asm
; 链接(64位系统需要 elf_i386 选项):ld -m elf_i386 helloworld.o -o helloworld
; 运行:./helloworld
 
SECTION .data
msg     db      'Hello World!', 0Ah     ; 初始化变量msg
 
SECTION .text
global  _start
 
_start:
    mov     edx, 13     ; 待写入的字节数(每个字母一个字节,再加上换行符0Ah)
    mov     ecx, msg    ; 将msg的内存地址移入ecx
    mov     ebx, 1      ; 表示写入到标准输出STDOUT
    mov     eax, 4      ; 调用SYS_WRITE(OPCODE是4)
    int     80h