如果我的術語不正確,請原諒我。將命令行參數正確放置到堆棧上
我想實現一個基於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打印到屏幕上。
.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
我已經看過堆棧如何爲函數調用做準備,以爲它可能是一個類似的過程,但我仍處於斷開狀態。 有什麼想法?
進度:我想我可能已經找到了一個粗略的工作。我完全從主聲明中刪除了argc和argv。有兩個原因,1。我只會填充我自己的變量,在我的寵物操作系統中可能還有其他一些缺失的東西,gcc在編譯這些測試程序時會假定其工作。 現在我手動從內聯程序集中取出了不太難的值。儘管如此,仍然希望能夠正常工作。 addl $ 4,%esp \t#stack on stack; movl(%esp),%eax \t#轉到下一個 – tman