Linux中國

linux簡單之美

(一)

話說windows也有syscall,這是必須的。但是win的syscall可以直接call嗎?可以是

可以但是破費周折,搞成SDT之類的複雜概念。下面看看linux是如何做的吧。

section .data
msg db "hello hopy!",0x0a

section .text
global _start

_start:
    mov eax,4
    mov ebx,1
    mov ecx,msg
    mov edx,12
    int 0x80

    mov eax,1
    mov ebx,0
    int 0x80

關鍵是系統調用號要知道,開始找的是usr/include/asm-gen*/unistd.h,

可是都不對。後來找的是usr/include/x86_64_linux_gnu/asm/下的頭文件,

有2個,分別對應x86和x64.、編譯連接指令如下:

nasm -f elf main.asm
ld main.o

運行,段轉儲錯誤鳥,查了一下,本貓用的是x64位的linux,所以要生成

x64位的程序,或者指明是x86的程序,我選擇後者:

ld -m elf_i386 -o main main.o

哦鳥!

(二)

我們在前一章中看到了如何僅僅用syscall做一些簡單的事,現在我們看能不能直接調用

C標準庫中的函數快速做一些"複雜"的事:

section .data
    ft db "now is %d",10

section .text
extern puts
extern exit
extern sleep
extern printf
global main

main:
    mov edi,11
again:  
    dec edi
    push edi
    push ft
    call printf

    push 1
    call sleep

    cmp edi,0
    jnz again

    push msg
    call puts

    push 0
    call exit

msg:
 db "happy xxx day!",0

以上代碼功能很簡單,從10倒數到0,然後列印一行,最後結束.與之前代碼不同的是其中

調用了C標準庫中的函數.編譯和以前一樣:

nasm -e elf main.asm

我們看看怎麼連接:

gcc -m32 -o main main.o

好鳥!運行正常.

值得注意的是:我的OS是ubuntu64,而asm代碼中是32位的,如果開始用

ld -m elf_i386 -lc -o main main.o

的方式,首先會提示找不到c庫,這可以進入/usr/lib,然後使用

sudo ln -sv /lib/i386-linux-gun/libc.so.6 libc.so

創建軟連接解決.

但在運行時提示無法找到可執行文件!該文件明明在的!

遂用gcc來連接,但要將_start改為main,還要裝載32庫

sudo apt-get install ia32-libs

還會提示找不到h文件,這時再裝載庫

sudo apt-get install g++-multilib

還有2族庫,如有必要也可載入:

sudo apt-get install libc6:i386 libgcc1:i386 gcc-4.6-base:i386 
libstdc++5:i386 libstdc++6:i386
sudo apt-get install libc6-i386

最後要說的是,一些C代碼在用std=c99編譯時會發現提示無法獲取結構大小,

這時改成如下即可:

gcc -D_GNU_SOURCE -std=c99 main.c

(三)

在(二)中我們嘗試使用了C庫的函數完成功能,那麼能不能用syscall方式

來搞呢?顯然可以!

section .data
    ft db "now is X",10

section .text
global _start

_start:
    mov edi,10
again:
    dec edi
    mov eax,edi
    add eax,0x30
    mov byte [ft+7],al

    mov eax,4
    mov ebx,1
    mov ecx,ft
    mov edx,9
    int 0x80

    mov eax,162
    push 0
    push 1
    mov ebx,esp
    mov ecx,0
    int 0x80

    cmp edi,0
    jnz again

    mov eax,4
    mov ebx,1
    mov ecx,msg
    mov edx,15
    int 0x80

    mov eax,1
    mov ebx,0
    int 0x80

msg:
 db "happy xxx day!",10

--

nasm -f elf main.asm
ld -m elf_i386 -o main main.o

在代碼中延時使用的是nanosleep,其他和第一篇一致,只不過做了一個bin->ascii的小轉換.

via: http://blog.csdn.net/mydo/article/details/8224352 http://blog.csdn.net/mydo/article/details/8452386 http://blog.csdn.net/mydo/article/details/8452417


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國