//countString.asm 是用来自动统计字符串长度,然后输出该字符串[08:12:56] vi countString.asm[08:13:28] nasm -f elf64 countString.asm[08:13:30] ld -o countString countString.o[08:13:32] ./countString hello,linux world,and hello asm[08:13:35] cat countString.asmsection .datamsg db 'hello,linux world,and hello asm',0Ahsection .textglobal _start_start:mov ebx,msg ;use ebx,because then need sub eax,ebxmov eax,ebxnextchar:cmp byte[eax],0 ;compare whether is endjz finished ;is end,go to finishedinc eax ;countjmp nextchar ;continuefinished:sub eax,ebx ;string length eax=ebx-eaxmov edx,eax ;edx is used to save lengthmov ecx,msg ;make ecx become msg contentmov ebx,1 ;write to stdoutmov eax,4 ;system call writeint 80hmov ebx,0 ;return statusmov eax,1 ;system call exitint 80h
那么现在我们来换个法子显示字符串。有一点需要注意,寄存器的名称我全部改为rax,rbx等以r开头的,这个是64位寄存器的意思,eax之类的是32位,ax的应该是16位了,注释那个我就懒得改过来了
[08:42:58] nasm -g -f elf64 countString.asm[08:43:00] ld -o countString countString.o[08:43:01] ./countString hello,linux world,and hello asm![08:43:03] cat countString.asmsection .datamsg db 'hello,linux world,and hello asm!',0Ahsection .textglobal _start_start:mov rbx,msg ;use ebx,because then need sub eax,ebx call strlen ;call our function to calculate the length of the string,类似c语言的函数之类的mov rdx,rax ;edx is used to save lengthmov rcx,msg ;make ecx become msg contentmov rbx,1 ;write to stdoutmov rax,4 ;system call writeint 80hmov rbx,0 ;return statusmov rax,1 ;system call exitint 80hstrlen:push rbx ;push rbx,because then need rbxmov rax,rbxnextchar:cmp byte[rax],0 ;compare whether is endjz finished ;is end,go to finishedinc rax ;countjmp nextchar ;continuefinished:pop rbx ;get rbxsub rax,rbx ;string length eax=ebx-eaxret ; return to where the function was called
接着我们来试试包含外部文件
;functions.asm ; int slen(String message); String length calculation functionslen: push ebx mov ebx, eaxnextchar: cmp byte [eax], 0 jz finished inc eax jmp nextcharfinished: sub eax, ebx pop ebx ret; void sprint(String message); String printing functionsprint: push edx push ecx push ebx push eax call slen mov edx, eax pop eax mov ecx, eax mov ebx, 1 mov eax, 4 int 80h pop ebx pop ecx pop edx ret; void exit(); Exit program and restore resourcesquit: mov ebx, 0 mov eax, 1 int 80h ret;--------------------------------------------------------;--------------------------------------------------------;helloworld-inc.asm%include 'functions.asm' ; include our external fileSECTION .datamsg1 db 'Hello, brave new world!', 0Ah ; our first message stringmsg2 db 'This is how we recycle in NASM.', 0Ah ; our second message stringSECTION .textglobal _start_start: mov eax, msg1 ; move the address of our first message string into EAX call sprint ; call our string printing function mov eax, msg2 ; move the address of our second message string into EAX call sprint ; call our string printing function call quit ; call our quit function;---------------------------------------------------在第一个fuctions.asm的基础上修改helloworld-inc.asm,代码如下,dec减去,ecx是用来保存程序参数的,相乘mul ebx,multiply eax by ebx%include 'functions.asm'SECTION .textglobal _start_start: pop ecx ; first value on the stack is the number of argumentsnextArg: cmp ecx, 0h ; check to see if we have any arguments left jz noMoreArgs ; if zero flag is set jump to noMoreArgs label (jumping over the end of the loop) pop eax ; pop the next argument off the stack call sprintLF ; call our print with linefeed function dec ecx ; decrease ecx (number of arguments left) by 1 jmp nextArg ; jump to nextArg labelnoMoreArgs: call quit