"Hello World!"出力するシェルコードを作成するには
アセンブリ言語が必要だということでいろいろ調べているのですが
結局、
アセンブリ言語で関数のwriteを呼び出すパターン
(ヘッダーファイルから定義を参照して最終的にシステムコールを使う場合)
s
1レジスタ設定など・・・(ここから上) 2call _write
と、
アセンブリ言語で syscall関数を使って間接的に
writeシステムコールを使う場合。引用元
s
1.intel_syntax noprefix # コードの書式 2.global main # 実行開始地点のラベル 3 4main: 5# 前処理 6 push rbp 7 mov rbp, rsp 8 9# 文字列'Hi!'をスタックに格納する 10 push 0xA216948 11 12# ステップ1 system call number で'1'(=writeに対応)を指定する 13 mov rax, 1 14 15# ステップ2 writeのシステムコールに渡す引数をレジスタにセットする 16 mov rdi, 1 # 書き出し対象のファイルディスクリプタで1(標準出力)をセットする 17 mov rsi, rsp # スタックの先頭アドレス(文字`H`が入っている)をセットする 18 mov rdx, 4 # 出力する文字列のサイズをセットする 19 20# ステップ3 システムコールを発行する 21 syscall 22 23# 後処理 24 mov rsp, rbp 25 pop rbp 26 ret
これら2つは何が違うのですか?
勝手な考察
一つ目は、
call _write より<unistd.h>
という名前のヘッダーファイルを参照し、
最終的に機械語のwriteシステムコールを発行する。
二つ目は
・・・
syscall
より、syscall関数が定義されている
<sys/syscall.h>という名前のファイルを参照し、
最終的に機械語のwriteシステムコールを発行する。
・・・何が違うんですか?
レジスタの設定、スタックに引数を積むかどうか
など、設定に違いはありますが
やっていることは結局同じな気がしますが
これら2つは何が違うんでしょうか?
分からないので教えてください。(環境自体の相違性?)
(今回も結構な勘違いをしているような・・・)
回答2件
あなたの回答
tips
プレビュー