您现在的位置是:首页 > 服务器相关

nasm第一个程序

batsom2021-09-05服务器相关

简介nasm第一个程序

(1)数据段(.data section)

数据段主要用来“声明初始化数据”,换句话说,是用来定义常“变量”的,这个“变量”主要是指在程序中不会一直变化,定义后就会保持不变。通常数据段都是用来定义常用的标号,比如:文件名、缓存大小等等,当然,你也可以使用 EQU 这个指令来实现。定义常“变量”可以使用的指令有:DB、DW、DD、DQ和DT,例如:

section    .data
    message:        db    'Hello World!'    ;声明一个字节类型(byte)的字符数组
    msglength:    equ    12            ;声明字节数组的长度
    buffersiz:        dw    1024            ;声明一个1024大小(字)的缓存

(2)变量段(.bss section)
该段主要是用来定义变量的,这里可以使用的指令有:RESB、RESW、EWSD、EWSQ和REST等,这些指令可以用来预留一些内存空间给定义的变量。例如:

section    .bss
    filename:        resb    255    ;定义255个字节的内存空间
    number:        resb    1    
    bignum:        resw    1    ;定义1个字的内存空间(1字=2字节)
    realarray:        resq    10    ;定义10个reals大小的数组

(3)代码段(.text section)

这部分主要是用来写汇编代码的,通常,代码段必须以 global _start(_start为标号,自定义)开头,他的主要含义是告诉内核程序是从这里开始的,内核在看到这部分变编译后的信息,就会将相关的CS:IP指向这里,然后开始执行程序。就和C函数中的main()函数类似。例如:
section    .text
    global    _start
    
    _start:
        pop    ebx    ;这里是程序开始执行的入口

程序第一个例子都是hello world,有谁能告诉我为啥?

section .data
massage: db "Hello world!"
Len: equ $ - massage

section .text
   global _start

_start:
mov eax,4 ; 4号调用 sys_write的系统调用
mov ebx,1 ; ebx送1表示输出,参数1,文件描述符,stdout是1
mov ecx,massage ; 字符串的首地址送入ecx
mov edx,Len ; 字符串的长度送入edx
int 80h ; 输出字串
mov eax,1 ; sys_exit的系统调用
mov ebx,0 ;sys_exit的返回参数0,表示无错误
int 80h ; 系统调用

编译:
nasm -g -f elf32 hello.asm -o hello.o
ld -g -m elf_i386 -o hello hello.o

调试:
gdb hello

(调试指令:http://www.flaotw.com/latest/2021-09-05/169.html)


代码说明:
Linux下的系统调用和DOS下的系统调用类似,主要通过以下几个步骤:
(1)将你的系统调用号放进EAX中(因为我们是在32位下,所以使用32位的EAX寄存器)。
(2)设置系统调用参数,并且依次将参数放进EBX、ECX、EDX、ESX、EDI和EBP。
(3)调用相关中断(对应Linux来说是 80h;对于DO来说是 21h)。
(4)最后的调用结果会返回到EAX中保存。

说明:第二步中的参数是按照顺序放置的,比如第一个参数放在EBX中,第二个参数放在ECX中,…第5个参数放在EDI中。但是只有Linux2.4以后的版本才至此第6个参数EBP,以上的版本只支持前5个参数。如果有多于6个参数,则EBX用来存放参数列表在内存中的位置,但是通常情况下是不会多于6个参数的。

例如:
mov    eax,1    ;exit系统调用
mov    ebx,0    ;返回参数是0
int    80h    ;使用80h中断,然后系统内核便开始调用函数


 

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

随便看看

文章排行

本栏推荐

栏目更新