使用YASM编程 - 04

在linux下使用yasm
先介绍 64位的汇编开发

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;test.asm
;在Linux下使用yasm
;安装: yasm sudo apt install yasm
;编译: yasm -f elf64 -o test64.o test.asm
;链接  ld -e start -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test64 -lc  test64.o
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
bits 64
section .data
    hello: db "hello",0x0a,0
    format: db "msg:%s %d %d %d %d %d %d ",0x0a,0
    tmp1 equ 1
    tmp2 equ 2
    tmp3 equ 3
    tmp4 equ 4
    tmp5 equ 5
    tmp6 equ 6
extern printf
extern exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;实现在x64 下使用的 invoke
;自动将参数压入 rdi rsi rdx rcx r8 r9
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;%ifidn 两个标识符是否相等
;%ifid 是否id;%ifnum 是否数字%ifstr 是否字符串
%macro invoke 1-*
    %define jtmp %1
    %define jcount %0
    %if %0>1
        %if %0>=2
            mov rdi,%2
        %endif

        %if %0>=3
            mov rsi,%3
        %endif

        %if %0>=4
            mov rdx,%4
        %endif

        %if %0>=5
            mov rcx,%5
        %endif

        %if %0>=6
            mov r8,%6
        %endif

        %if %0>=7
            mov r9,%7
        %endif

        %if %0-7>0
            %rep %0-7
                ;参数旋转,最后一个参数为1
                %rotate -1
                ;将 %1 参数入栈
                push %1
            %endrep
        %endif

    %endif
    call jtmp
    %if jcount>6
        add rsp,(jcount-7)*8
    %endif
%endmacro

section .text
    global start
start:
; 在Linux x64 调用约定为
; rdi
; rsi
; rcx
; rdx
; r8
; r9
; 多余的参数使用栈来传递
    invoke printf,format,hello,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6
; 如果不调用exit ,退出的时候会崩溃
    invoke exit,0
    ret

再介绍32位的开发:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;test32.asm
;在Linux下使用yasm
;安装yasm: sudo apt install yasm
;编译: yasm -f elf32 -o test32.o test32.asm
;链接  ld -m elf_i386 -e start -dynamic-linker /lib32/ld-linux.so.2 -o test32 -lc test32.o
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

section .data
hello: db "hello yasm",0x0a,0

%macro invoke 1-*
    %define jtmp %1
    %define jcount %0
    %if %0>0
        %rep %0-1
            ;参数旋转,最后一个参数为1
            %rotate -1
            ;将 %1 参数入栈
            push %1
        %endrep
    %endif
    call jtmp
    %if jcount>1
        add esp,(jcount-1)*4
    %endif
%endmacro

extern printf
extern exit
section .text
global start
start:
    invoke printf,hello
;这里不调用exit会崩溃
    invoke exit,0
    ret

猜你喜欢

转载自blog.csdn.net/justin_bkdrong/article/details/77839368
今日推荐