汇编2——完整的例子集合
//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.asm
section .data
msg db 'hello,linux world,and hello asm',0Ah
section .text
global _start
_start:
mov ebx,msg ;use ebx,because then need sub eax,ebx
mov eax,ebx
nextchar:
cmp byte[eax],0 ;compare whether is end
jz finished ;is end,go to finished
inc eax ;count
jmp nextchar ;continue
finished:
sub eax,ebx ;string length eax=ebx-eax
mov edx,eax ;edx is used to save length
mov ecx,msg ;make ecx become msg content
mov ebx,1 ;write to stdout
mov eax,4 ;system call write
int 80h
mov ebx,0 ;return status
mov eax,1 ;system call exit
int 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.asm
section .data
msg db 'hello,linux world,and hello asm!',0Ah
section .text
global _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 length
mov rcx,msg ;make ecx become msg content
mov rbx,1 ;write to stdout
mov rax,4 ;system call write
int 80h
mov rbx,0 ;return status
mov rax,1 ;system call exit
int 80h
strlen:
push rbx ;push rbx,because then need rbx
mov rax,rbx
nextchar:
cmp byte[rax],0 ;compare whether is end
jz finished ;is end,go to finished
inc rax ;count
jmp nextchar ;continue
finished:
pop rbx ;get rbx
sub rax,rbx ;string length eax=ebx-eax
ret ; return to where the function was called
接着我们来试试包含外部文件
;functions.asm
; int slen(String message)
; String length calculation function
slen:
push ebx
mov ebx, eax
nextchar:
cmp byte [eax], 0
jz finished
inc eax
jmp nextchar
finished:
sub eax, ebx
pop ebx
ret
; void sprint(String message)
; String printing function
sprint:
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 resources
quit:
mov ebx, 0
mov eax, 1
int 80h
ret
;--------------------------------------------------------
;--------------------------------------------------------
;helloworld-inc.asm
%include 'functions.asm' ; include our external file
SECTION .data
msg1 db 'Hello, brave new world!', 0Ah ; our first message string
msg2 db 'This is how we recycle in NASM.', 0Ah ; our second message string
SECTION .text
global _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 .text
global _start
_start:
pop ecx ; first value on the stack is the number of arguments
nextArg:
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 label
noMoreArgs:
call quit