ちょっと学習したい事柄があり、その過程でアセンブラを勉強中。
HelloWorldから勉強しており、システムコールの呼び出し方についてのメモ。
環境
- CentOS7 on Windows(VMWare)
- x86_64
システムコールの呼び出し方
ベースのコードをこちらのページから拝借。
int 0x80
まずint 0x80
による呼び出し方法
section .data
message db 'Hello, World', 0x0a
length equ $ -message
section .text
global _start
_start:
mov ecx, message
mov edx, length
mov eax, 4
mov ebx, 1
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
Hello, World
int 0x80
命令の場合、eaxレジスタにシステムコール番号を入力することが必要なようです。上記の例では4です。で、これが何のシステムコールかということは/usr/include/asm/unistd_32.h
に記載されているようです。
以下に一部を抜粋すると4のところに出力の命令が来ているのが分かります。
#ifndef _ASM_X86_UNISTD_32_H
#define _ASM_X86_UNISTD_32_H 1
#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
#define __NR_write 4
syscall
上記ですが、unistd_32.h
からも分かるとおりx86のシステムコール番号を参照した実行方法のようです。使用しているOSはx86_64なので、せっかくだからx86_64のシステムコール番号で呼び出したいところです。これはsyscall
命令を使用すると呼び出せるとのこと。
またシステムコール番号はunistd_64.hを参照すれば分かります。今度は1が出力なのでそれを指定します。
指定するレジスタ名も異なるようです。具体的にはこちらを参照。
section .data
message db 'Hello, World', 0x0a
length equ $ -message
section .text
global _start
_start:
mov rsi, message ←変更点
mov rdx, length ←変更点
mov rax, 1 ←変更点
mov rdi, 1 ←変更点
syscall
mov eax, 1
mov ebx, 0
int 0x80
Hello, World
参考
X86 Assembly/Interfacing with Linux - Wikibooks, open books for an open world http://en.wikibooks.org/wiki/X86_Assembly/Interfacing_with_Linux
Linux で NASM http://homepage2.nifty.com/hanpen/assemblry.html
売り上げランキング: 10,873