linux简单之美

    xiaoxiao2024-01-11  172

    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的小转换.

    原文发布时间:2014-06-24

    本文来自云栖合作伙伴“linux中国”

    最新回复(0)