システムコールの呼び出し方メモ

  • 8
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

ちょっと学習したい事柄があり、その過程でアセンブラを勉強中。
HelloWorldから勉強しており、システムコールの呼び出し方についてのメモ。

環境

  • CentOS7 on Windows(VMWare)
  • x86_64

システムコールの呼び出し方

ベースのコードをこちらのページから拝借。

int 0x80

まずint 0x80による呼び出し方法

hello.asm
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のところに出力の命令が来ているのが分かります。

unistd_32.h
#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が出力なのでそれを指定します。
指定するレジスタ名も異なるようです。具体的にはこちらを参照。

hello.asm
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

32ビットコンピュータをやさしく語る はじめて読む486 (アスキー書籍)
KADOKAWA / アスキー・メディアワークス (2014-10-21)
売り上げランキング: 10,873