linux下64位彙編的系統調用(4)

來源:互聯網
上載者:User

標籤:linux   syscall   nasm   mmap   系統調用   

經過上一篇的鋪墊貌似可以很輕鬆的用彙編寫出mmap的代碼來,可仔細一看,還是有不少問題需要解決:

1.系統調用mmap如果出錯並不直接返回MAP_FAILED(-1),而是一個“類似”值;C庫中的mmap函數對其做了封裝,使其最終返回-1;如果我們直接調用mmap syscall,則這些事必須自己來做。

2.C庫函數如果出錯會設定errno的值,而在彙編中沒法直接用:

extern errno

的方法使用外部的值,串連時會報錯:

/usr/bin/ld: errno: TLS definition in /lib/x86_64-linux-gnu/libc.so.6 section .tbss mismatches non-TLS reference in p.o/lib/x86_64-linux-gnu/libc.so.6: error adding symbols: 錯誤的值

C語言的解決辦法很簡單,直接把:

extern int errno;//替換為#include <errno.h>

但nasm下這招沒法使;我們先看一下errno對應的C代碼:

#define errno() *errnofunc()int *errnofunc() {    int *errnoptr = get_thread_data(ERRNOPTR);    return errnoptr;}

可以看到其調用另一個函數,在nasm中我們可以大致這麼寫:

extern __errno_locationcall __errno_locationmov rax,qword [rax]

不過貌似也不太對 :( ,不過我們可以在mmap系統調用後自己操作errno的值,以下代碼將填充變數errno的值並且如果出錯將修正mmap的傳回值為-1:

section .dataerrno dq 0;mmap syscall 之後cmp rax,0xfffffffffffff001jb nextpush raxneg raxmov [errno],raxpop raxor rax,-1next:;處理mmap返回後的邏輯

最後的代碼如下:

section .data    errno dq 0    addr dq 0MAP_FAILED equ -1;MAP_LEN equ 40960MAP_LEN equ 0xffffffffffffffffPROT_READ_WRITE equ 3MAP_SHARED_ANON equ 33;MAP_SHARED_ANON equ 0x20section .text;extern errnoextern __errno_locationextern strerrorextern printf;if use ld;global _start;if use gccglobal main;_start:main:    and rsp,~0xffff            ;堆棧對齊 equ 0xffffffffffff0000    mov rax,9               ;mmap NO    mov rdi,0               ;map address    mov rsi,MAP_LEN             ;map size    mov rdx,PROT_READ_WRITE    mov r10,MAP_SHARED_ANON    mov r8,-1               ;忽略fd    mov r9,0                ;offset    syscall    cmp rax,0xfffffffffffff001    jb next    push rax    neg rax    mov [errno],rax    pop rax    or rax,-1next:    cmp rax,MAP_FAILED    ;cmp rax,0    ;js map_failed    je map_failed    mov [addr],rax    mov rsi,[addr]    mov rdi,msg_success    call printf    mov rax,11    mov rdi,addr    mov rsi,MAP_LEN    syscall    jmp exitmap_failed:     ;mov rdi,0xb    ;call __errno_location    ;mov rax,qword [rax]    ;mov rsi,[errno]    mov rdi,[errno]    call strerror    mov rsi,rax    mov rdi,msg_failed    call printfexit:    mov rax,60      ;exit NO    mov rdi,0       ;error_code    syscall    msg_success: db "map successed , addr at %p",0ax,0    msg_failed: db "map failed ,due to %s",0ax,0

編譯串連:

nasm -f elf64 p.sgcc -o p p.o

如果mmap成功結果如下:

wisy@wisy-pad:~/src/asm_src/nasm_src/linux$ ./pmap successed , addr at 0x7fbe5c94e000

可以用strace查看其返回的syscall:

mmap(NULL, 40960, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0) = 0x7fc6b2397000

如果mmap出錯則會顯示出錯原因:

//將MAP_LEN 設為超大的值./pmap failed ,due to Cannot allocate memory//傳遞給flags錯誤的參數./pmap failed ,due to Invalid argument

linux下64位彙編的系統調用(4)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.