linux下64位汇编的系统调用(3)

背景知识基本交代清楚了,下面我们实际写一个小例子看一下。代码的功能很简单,显示一行文本,然后退出。我们使用了syscall中的write和exit调用,查一下前面的调用号和参数,我们初步总结如下:

write(即sys_write)调用号为1,需传递3个参数

unsigned int fd
const char *buf
size_t count

exit(sys_exit)调用号为60,只需传递一个错误码

int error_code

如果该值为0表示程序执行成功。

因为以上两个调用最多的也只有3个参数,所以我们依次只会用到3个寄存器rdi,rsi和rdx。

实际代码如下:

section .text
;if use ld
global _start
;if use gcc
;global main
_start:
;main
    mov rax,1       ;write NO
    mov rdx,1       ;fd
    mov rsi,msg     ;addr of msg string
    mov rdx,msg_len ;lenght of msg string
    syscall

    mov rax,60      ;exit NO
    mov rdi,0       ;error_code
    syscall

    msg: db "Hello World!",0xa
    msg_len:equ $-msg

编译连接命令如下:

nasm -f elf64 p.s
ld -o p p.o

如果是mac os x系统下命令如下:

nasm -f macho64 p.s
ld -o p p.o

因为本博的标题是linux下的汇编,所以mac os x下请参考本猫另一篇博文[Mac OS X64位以及32位汇编系统调用]。

如果你要生成32位的代码,在编译时把elf64改为elf32就可以了,不过我前面说过:32位和64位汇编结构变化较大,光改这个是没办法运行成功的。

不出所料代码运行输出一行:Hello World!并且程序返回后用echo $?看,应该为0.

这个例子很简单,下面看一下稍微复杂点的调用:mmap,该调用共有6个参数,我们再一次总结如下:

mmap(sys_mmap) 系统调用号为9,参数分别为:

unsigned long addr
unsigned long len
unsigned long prot
unsigned long flags
unsigned long fd
unsigned long offset

第一个参数是需要映射到的地址,我们这里传0,表示不关心映射到哪;第二个参数是映射空间的大小;第三个参数表示映射区域的保护方式,有很多种,我们这里只让它可读可写即可,所以只用到2者的组合:

PROT_WRITE|PROT_READ

第四个参数是映射区域的一些特性,有很多组合。这里只用MAP_SHARED|MAP_ANONYMOUS,后者表示建立匿名映射,会忽略参数fd,所以不设及文件。

第五个参数就是fd,前面说了可以忽略,所以我们传递-1;最后一个参数是映射的偏移量,我们也传递0.

该调用如果成功返回映射区域内存的起始地址,否则返回MAP_FAILED(-1),错误原因存于errno中,我们可以用strerror(errno)查看具体含义。不过该函数是C库中的,这里我们捎带的用一下。

提到mmap我们不得不提到munmap,用猜大家也知道该调用的含义吧:

munmap(sys_munmap) 调用号为11,需传递2个参数:

unsigned long start
size_t len
时间: 2024-08-05 15:25:04

linux下64位汇编的系统调用(3)的相关文章

linux下64位汇编的系统调用(5)

看到这里大家都基本知道了如何进行linux下的汇编系统调用:不过有些童鞋可能会问:那些C库中函数里为我们解决的额外汇编代码你是怎么知道的? 好吧,我承认:我是通过逆向知道的,这貌似有点犯规的嫌疑- 比如举个例子,那上一篇里的mmap C库函数来说,首先写一个C代码: #include <stdlib.h> #include <stdio.h> #include <stdbool.h> #include <sys/mman.h> #include <sy

linux下64位汇编的系统调用(4)

经过上一篇的铺垫貌似可以很轻松的用汇编写出mmap的代码来,可仔细一看,还是有不少问题需要解决: 1.系统调用mmap如果出错并不直接返回MAP_FAILED(-1),而是一个"类似"值:C库中的mmap函数对其做了包装,使其最终返回-1:如果我们直接调用mmap syscall,则这些事必须自己来做. 2.C库函数如果出错会设置errno的值,而在汇编中没法直接用: extern errno 的方法使用外部的值,连接时会报错: /usr/bin/ld: errno: TLS defi

Mac OS X下64位汇编与Linux下64位汇编的一些不同

1 首先系统调用号大大的不同:mac64和linux32的系统调用号也不同(虽然局部可能有相同) 2 mac64的系统调用号在: /usr/include/sys/syscall.h 可以查到,但是调用的时候其值要加上0x2000000,可以写一个宏处理: %define mk64 0x2000000+ 使用方式如下: mov rax,mk64 1 ;exit NO mov rdi,0 ;error_code syscall 3 如果在mac64下汇编要与C库相链接,所有extern符号名前要加

win7win8 64位汇编开发环境合集安装与设置

win7win8 64位汇编开发环境合集安装与设置 下载 win7 win8  64位汇编开发环境.rar 下载地址(免积分下载) http://download.csdn.net/detail/liuchuang_mfc/9473974 打开DOSBox0.74-win32-installer.exe进行安装 将debug.exe,edit.com,link.exe,masm.exe这几个程序拷贝到d:\myassembly目录下就可以 找到你安装的路径目录下.以记事本打开文件:DOSBox

Windows下64位Apache服务器的安装

转自:http://www.blogjava.net/greatyuqing/archive/2013/02/13/395308.html 首先需要说明的是,Apaceh服务器没有官方的64位版本,只有民间的高手自己制作的.下面是具体的安装步骤. 在https://blackdot.be/download-archive/ 下载64位的Apache服务器.目前的版本是2.2.19,下载之后的压缩包名为httpd-2.2.19-win64.rar: 将该包解压至一个目录,如我的目录为E:\Apac

Red Hat Enterprise Linux 6 64位详细安装教程

首先声明,Linux的高手请直接单击网页右上角退出. 对于linux的新手来说,安装linux操作系统是比较麻烦的一件事,这次为大家带来Red Hat Enterprise Linux 6 64位安装的详细教程. 本次演示仍然需要用到虚拟机,那我们就一步一步来进行,从创建新的虚拟机开始. 这次我们选择自定义. 接着默认选择,下一步即可. 这里我们需要选择稍后安装操作系统,一定要切记不好直接选择iso镜像,要不然系统会默认安装英文,很麻烦. 这里我们要选择Linux 版本就是我们今天要演示的版本R

虚拟机上安装 Red Hat Enterprise Linux 7 64位

一 .准备 1)可以支持64位 电脑一台: 2)安装VMware Workstaition 10及以上版本: 3)下载Red Hat Enterprise Linux 7 64位镜像: 二.安装 1)打开VMware,创建新的虚拟机

64位汇编第二讲——64位汇编中局部变量使用及抬栈方法29171230

一.纯写64位汇编时局部变量处理和参数寄存器保存位置 纯写64位汇编和用VS2013写64位C代码生成的汇编会有一些格式上的区别,VS2013写64位C代码生成的汇编中是没用到栈基址寄存器rbp的,但是纯写汇编时只要申明了参数和使用了@LOCAL定义的局部变量,就会用到rbp.且看如下例子:1)用C写64位程序空函数生成的汇编代码, ;C代码 void FunTest2() { } ;汇编代码 000000013F753290 40 57 push rdi 000000013F753292 5F

解决VMware下64位linux系统不支持全虚拟化(vmx)

一.前提: cpu支持Inter VT-X或AMD虚拟化技术,具体参考官网说明. 二.问题描述: 物理机下,vmware workstation能安装64位CentOS系统,处理器Inter i3 M390,且支持Inter VT-X虚拟化技术,物理机BIOS中已打开Inter虚拟化开关(自己找),既然能安装64位系统,说明物理机BIOS中支持虚拟化开关已打开. 半虚拟化为pae 全虚拟化为vmx(Inter).svm(AMD) # uname -r 2.6.32-358.el6.x86_64