汇编编程原则
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 ; 调用内核功能