用語が正しくない場合はご容赦ください。
x86 gnu c ベースのシステムを実装しようとしていますが、コマンドライン引数をプログラムに渡すことができます。プログラム内でそれらにアクセスすることと混同しないでください。実際には、実行をユーザー プログラムに渡す前にスタックを設定します。
私が収集したものから、argc と argv はスタックにプッシュされますが、何かが欠けているのはその構築プロセスです。以下は、別のプログラムを実行する方法です。
__asm__ __volatile__ ("pushl %%ds\n" /* save data and extra segment registers */
"pushl %%es\n"
"movl %%esp, %%ebx\n"
"movl %%ebx, oldsp\n"
"movl %%ss, %%ebx\n"
"movl %%ebx, oldss\n"
"movl %0, %%ds\n" /* set data segment to new user base */
"movl %0, %%ss\n"
"movl $0xfff0, %%ebx\n" /* start of the new user stack pointer */
"movl %%ebx, %%esp\n"
"movl %2, %%eax\n" /* place i into eax - push it onto the stack*/
"pushl %%eax\n"
"pushl %%eax\n"
"lcallw *%%fs:(%1)\n"
"movl %%fs:oldss, %%ebx\n"
"movl %%ebx, %%ss\n"
"movl %%fs:oldsp, %%ebx\n"
"movl %%ebx, %%esp\n"
"popl %%es\n" /* restore old segment registers */
"popl %%ds\n"
:
:"a" (userbase), "d" (&useg), "r" (i)
:"%ebx", "eax", "memory"); /* prevents gcc from optimizing useg away*/
スタック ポインターが更新された後、値をスタックにプッシュできるという印象を受けました。スタックにプッシュした値を取得していないことは明らかなので、正しい方法で行っているかどうかさえよくわかりません。
以下は、argc print を画面に読み込もうとした単純なテスト プログラムです。
.file "prog3.c"
#APP
.code16gcc
call main
lretw
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "\r\nstring: %u"
#NO_APP
.section .text.startup,"ax",@progbits
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
movl 8(%ebp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits
同様のプロセスである可能性があると考えて、スタックが関数呼び出しに対してどのように準備されているかを見てきましたが、まだ切断されています。何かご意見は?