The Netwide Assembler (NASM) 汇编语言笔记

在汇编语言学习中找到的一个很好的入门Tutorial,所以摘录了一些比较重要的要点

1.一个汇编语言程序一般可分成3部分:

1) .data 区

     用来定义初始化变量 (但是此处的这些变量定义后在程序执行过程中是不允许改变的,所以是狭隘意义上的“变量”)

从C 语言的角度来说,这些宏,导入声明文件库等都应该在这块区域内。 这里可以使用EQU,DB, DW, DD, DQ  DT 等其他指令操作

section .data message: db 'Hello world!' ; 定义“变量” message,值为 'Hello world!' (不包含单引号) msglength: equ 12 ; 定义变量“msglength” 值为12 buffersize: dw 1024 ; 定义变量“buffersize”,数据类型为字,值为 1024

2)  .bss 

     此区域定义所有的变量, 可以使用 RESB, RESW, RESD, RESQ  REST 等指令操作在内存中申请为初始化的空间。 

filename: resb 255 ; 申请 255 bytes number: resb 1 ; 申请 1 byte bignum: resw 1 ; 申请 1 word (1 word = 2 bytes) realarray: resq 10 ; 申请一个包含 10 个(reals)实数数组

3)    .text 

汇编语言的所有操作定义在此区域。 .text 开头必须定义 global _start ,来告诉内核该程序的入口在哪里(类似于C或Java中的main函数,区别是它并不是一个函数,而只是一个起始点) 

section .text global _start _start: pop ebx ; 这是程序的起始处 . . .

2. 调用Linux的内核

Linux系统内核调用方式跟DOS是一样的。

     1. 将内核调用代码写进 EAX (这里以32位系统为例)

     2. 将内核调用所需要的参数写进 EBX, ECX 等

     3. 调用系统内核终止指令 (DOS是21h,而Linux则是80h)

     4. 内核调用的结果会返回在EAX


一般有6个寄存器用来调用系统内核。第一个参数写在 EBX,第二个写进ECX,然后是EDX,ESI,  EDI 最后是 EBP。

        mov	      eax,1 ; 调用系统内核 exit 功能 mov      ebx,0 ; exit 参数为 0 int	     80h ; 终止 80h, 就像是对系统说:"Yo, do this" 当然系统内核可供调用的功能是非常之多的,我们可以在 /usr/include/asm/ 这个目录下找到 unistd.h 文件(也可能是unistd32.h 或者unistd64.h)
里面包含你的系统支持的所有内核调用。 或者查看作者编辑的 Linux System Call Table 表格。

3. 第一个汇编程序 HelloWorld

  1. section .data  
  2.     hello:     db 'Hello world!',10    ; 'Hello world!' plus a linefeed character  
  3.     helloLen:  equ $-hello             ; Length of the 'Hello world!' string  
  4.                                        ; (I'll explain soon)  
  5. section .text  
  6.     global _start  
  7. _start:  
  8.     mov eax,4            ; The system call for write (sys_write)  
  9.     mov ebx,1            ; File descriptor 1 - standard output  
  10.     mov ecx,hello        ; Put the offset of hello in ecx  
  11.     mov edx,helloLen     ; helloLen is a constant, so we don't need to say  
  12.                          ;  mov edx,[helloLen] to get it's actual value  
  13.     int 80h              ; Call the kernel  
  14.     mov eax,1            ; The system call for exit (sys_exit)  
  15.     mov ebx,0            ; Exit with return code of 0 (no error)  
  16.     int 80h  

 

将以上代码保存在新的文件中,并以 hello.asm 命名该文件。

注:对 helloLen: equ  $-hello   行的分析:

在NASM中 美元符 $ 代表所在指令行的行首(也就是前一行的行末地址),前行末尾地址减去hello标志的地址就得到了hello所代表字符串的长度

 

编译 和链接库

  a. 编译 程序

   $ nasm -f elf hello.asm

   会生成一个 hello.o 文件


  b. 链接库

    $ ld -s -o  hello  hello.o  

    生成最终计算机可执行代码


  c. 运行程序

     $ ./hello


  恭喜你,你的第一个汇编处女程序成功运行啦!当然这个只是初步,要想真正了解汇编,接下来就多实践吧。

 

 :如果没有nasm编译软件,可以    sudo apt-get  install  nasm 安装 

 

 

 

3 运行程序时参数的处理

相对于DOS,对运行程序时输入的参数的调用更加简单直观。 因为在程序开始运行后,所有的参数都被保存在一个堆栈中,因此你要做的仅仅是用 pop 命令拿出所需要的参数。 以下给出一个例子(一个带有3个参数的程序):

./program foo bar 42

所对应的堆栈可以用下面的图来解释

4
program
foo
bar
42
参数的个数,注意程序名也被作为一个参数看待 (argc)
程序名(argv[0])
第一个参数(argv[1])
参数 2 (argv[2])
参数 3 (argv[3]) (注意: 这里是字符串 string "42",而不是数字 number 42)

 

 

 

 

原文地址:  http://www.cin.ufpe.br/~if817/arquivos/asmtut/index.html#intro

感谢作者 Derick Swanepoel (derick@maple.up.ac.za )


From:http://blog.csdn.net/jiangsq12345/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值