汇编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

posted on 2017-10-25 18:06  标配的小号  阅读(198)  评论(0编辑  收藏  举报

导航