汇编编程原则

section .data            	; 数据段声明
        same db "same",0ah 	; 0ah 是换行
        diff db "diff",0ah 	; 0ah 是换行
	data dd 3		; dd告诉汇编器占4个字节,db告诉汇编器占一个字节

section .stack
	stack db 1,3,2,4	;申请4字节的栈空间

section .text            	; 代码段声明
global _start            	; 指定入口函数
_start:                  	; 在屏幕上显示一个字符串
 
	mov eax,3		; 立即数
	mov ecx,eax 		; 寄存器寻址
	cmp ecx,3		; 判断ecx 是否等于3
	call print

	mov ecx,data  		;data的地址
	cmp ecx,3		;判断ecx 是否等于3
	call print

	mov ecx,[ecx+0]		;直接寻址(ecx中的地址作为地址+偏移)上的值
	cmp ecx,3		;判断ecx 是否等于3
	call print

	mov ecx,[data+0] 	;直接寻址(data的起始地址+偏移)上的值
	cmp ecx,3		;判断ecx 是否等于3
	call print


	call exit

print:		; 输出字符
	JE NEXT			;比较上次对比指令的结果,相同则跳转到next
		push 5		;传输第二个参数,字符串长度
		push diff	;传输第一个参数,字符串地址
	 	call loopShow
		add esp,8	;回收2个参数
		ret		;退出函数,否则回继续执行next
		
	NEXT: 
		push 5		;传输第二个参数,字符串长度
		push same	;传输第一个参数,字符串地址
		call loopShow
		add esp,8	;回收2个参数
		ret

loopShow:
	push ebp		; 保存上一个函数的ebp
	mov ebp,esp		; 得到当前函数的ebp

	push ecx		;当前函数中需要用到ecx,需要先保存现场
	push edx		;当前函数中需要用到edx,需要先保存现场

	mov edx, [ebp+12]	;读取第二个参数
	push edx		;第二个参数入栈,传到下个函数
	mov edx, [ebp+8]	;读取第一个参数
	push edx		;第一个参数入栈,传到下个函数
		
	mov ecx,3		;循环输出3次
	s:
  		call show	;调用函数输出字符串
	loop s 			;先ecx-=1,如果ecx=0,则退出循环 

	add esp,8		;回收2个参数的空间

	pop edx			;恢复现场
	pop ecx			;恢复现场
	pop ebp			; 恢复上个函数的ebp
	ret

show:
	push ebp		; 保存上一个函数的ebp
	mov ebp,esp		; 得到当前函数的ebp

	push eax		; 保存当前函数要用寄存器,保证不会覆盖原值
	push ecx		; 保存当前函数要用寄存器,保证不会覆盖原值
	push edx		; 保存当前函数要用寄存器,保证不会覆盖原值

        mov edx, [ebp+12]     	; 参数三:字符串长度
        mov ecx, [ebp+8]     	; 参数二:要显示的字符串
        mov ebx, 1       	; 参数一:文件描述符(stdout) 
        mov eax, 4       	; 系统调用号(sys_write) 
        int 0x80         	; 调用内核功能

	pop edx			;恢复现场
	pop ecx			;恢复现场
	pop eax			;恢复现场
	
	pop ebx			;恢复现场
	ret
	
exit:
        mov ebx, 0       	; 参数一:退出代码
        mov eax, 1       	; 系统调用号(sys_exit) 	
        int 0x80         	; 调用内核功能