nasm简介

NASM
	Netwide Assembler
	free

安装
	Linux, sudo apt-get install nasm
	Windows,下载安装包

学习汇编语言的目的
	更好的理解计算机组成和程序如何运行
	汇编程序更小更高效,能够用在一些环境苛刻的地方,如嵌入式
	在一些软件中有使用到汇编语言,如Linux内核,能够在C/C++中嵌入汇编语言

第一个程序
	编辑代码
		gedit hello.asm
		section .text
			global _start:
		_start:
			mov eax, 4
			mov ebx, 1
			mov ecx, string
			mov edx, length
			int 80h

			mov eax, 1
			mov ebx, 0
			int 80h

		section .data
			string: db 'Hello Word', 0Ah
			length: equ 13
		
		section .bss
			var: resb 1		; reserve 1 byte
	编译
		nasm -g -f elf64 -o hello.o hello.asm
	连接
		ld -o hello hello.o
	运行
		./hello
	反汇编
		objdump -d -M intel hello

sections in NASM
	一个NASM程序包含多个不同的section
	section .text
		程序部分,包含可执行指令
		是程序执行的开始处
	section .bss
		程序部分,包含未初始化的变量
		程序加载前,在文件中只包含section的描述信息,不包含数据
	section .data
		程序部分,包含初始化的变量
		程序加载前,在文件中包含section的描述信息和数据
	变量声明
		空间预留伪指令
			变量的声明
			RESx
		变量定义伪指令
			变量的声明和初始化
			Dx
		数据单元描述x
			b	byte			1 byte
			w	word			2 bytes
			d	double word		4 bytes
			q	quad word		8 bytes
			t	ten word		20 bytes
		注释符号";"
		二进制数,1010b
		十六进制,10h
		八进制,10o
		声明数组
			var: Dx 1,2,3
		使用字符串进行初始化
			string: db "Hello"
			string: db "H","e","l","l","o"
		重复定义
			var: times 100 Dx 1
		解引用
			一切符号都被作为数据使用,使用的是符号本身
			[符号],符号被作为地址使用,使用的是符号指向的数据或空间
			必要时,需要描述数据类型(长度)
				BYTE, WORD, DWORD, QWORD, TWORD
		声明常量
			var: equ 10h
	$和$$
		$,表示当前行汇编后的地址
		$$,表示当前section汇编后的首地址

X86基本指令集

Linux下基本输入输出
	调用约定
		中断类型码,使用int80h,在Windows中使用int21h
		中断操作码,eax,用于指定中断例程中的子程序
		其他操作数,放在其他通用寄存器中
	exit系统调用
		mov eax, 1
		mov ebx, 0
		int 80h
	read系统调用
		mov eax, 3	; system call number for read
		mov ebx, 0 	; source keyboard
		mov ecx, var	; pointer to memory location
		mov edx, dword[size]	; size of the string
		int 80h
	write系统调用
		mov eax, 4	; system call number for write
		mov ebx, 1 	; standard output device
		mov ecx, msg1	; pointer to output string
		mov edx, size1	; number of characters
		int 80h

子程序
	调用约定(Calling Convention)
		一组传参规则
		调用程序和子程序遵守的
	调用C库函数
		需要遵循C的调用约定
			参数,由调用程序入栈,由子程序出栈
			参数入栈的顺序为从右到左
		例子
			section .text
			global main
				; declaring the external functions to be used in the program
				extern scanf
				extern printf
			getint:
				push ebp
				mov ebp, esp

				sub esp, 2
				lea eax, [ebp-2]
				push eax
				push fmt1
				call scanf

				mov ax, word [ebp-2]
				mov word [num], ax

				mov esp, ebp
				pop ebp
				ret
			putint:
				push ebp
				mov ebp, esp

				sub esp, 2
				mov ax, word [num]
				mov [ebp-2], ax
				push fmt2
				call printf

				mov esp, ebp
				pop ebp
				ret
			main:
				mov eax, 4
				mov ebx, 1
				mov ecx, msg1
				mov edx, size1
				int 80h

				call getint
				mov ax, word[num]
				mov bx, ax
				mul bx
				mov word [num], ax
				call putint

			exit:
				mov ax, 1
				mov bx, 0
				int 80h

			section .data
				fmt1: db "%d", 0
				fmt2: db "Square of the number is: %d", 10, 0
				msg1: db "Enter an integer: "
				size1: db $-msg1
			
			section .bss
				num: resw 1
		编译
			nasm -g -f elf64 -o hello.o hello.asm
				失败,int.asm:7: error: instruction not supported in 64-bit mode
			编译成x86
				nasm -g -f elf -o hello.o hello.asm
				nasm -g -f elf32 -o hello.o hello.asm
		连接
			使用GCC默认连接
				gcc int.o -o int
				失败,i386 architecture of input file `int.o' is incompatible with i386:x86-64 output
				因为,GCC是x64的,会进行x64连接
					gcc -v
					Target: x86_64-linux-gnu
					64位的x86,即x64
			使用GCC进行x86连接
				安装库
					sudo apt-get install build-essential module-assistant  
					sudo apt-get install gcc-multilib g++-multilib
				gcc -m32 int.o -o int
			注意使用ld进行连接时
				默认进行x64连接
				若进行x86连接,可使用
					ld -m elf_i386

其他
	ALIGN n
		汇编控制
		下一地址,按照n对齐
		n可以为16等
		地址对齐,即是约定地址尾部为0(能被n整除),通过仅存储地址高位,实现小位数空间存大位数数据
			地址按照16位对齐,低4位始终为0,只需要存储高28位
	[BITS n]
		汇编控制
		表示section的位数,决定了跳转指令中偏移表示的位数			
		n可以为16,32等
			16位代码段中,跳转目标的偏移用16位表示
			32位代码段中,跳转目标的偏移用32位表示



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值