2013-05-05 57 views
0

爲了解決這個問題,我理解C語言,並且我仍然是Assembly中的初學者,所以我在這裏遇到了一些問題。彙編,多個參數-m32/linux(與C語言中的stdarg相同)

我有一些麻煩,採取多個參數,也許計數他們,如果我應該這樣做,並在我的彙編代碼中使用格式參數。

嘗試將一些字節添加到具有多個參數的字符串中。我知道如何將兩個第一個參數放在堆棧上,但第一個參數之後的其他參數是格式(如%s,%d,%c等),第一個參數是應該是變量i的格式想寫信給。 在C中,標準main有自變量。我可能想在這裏數論證論點!?我該怎麼做,如果這是如何做到的?

 .globl minisprintf 

# Name:   minisprintf 
# Synopsis:  A simplified sprintf 
# C-signature:  int minisprintf(unsigned char *res, unsigned char *format, ...); 
# Registers:  AL: for characters  
#     %ECX: first argument, res 
#     %EDX: second argument, args 
# 



minisprintf:     # minisprintf 

    pushl  %ebp   # start of 
    movl  %esp, %ebp  # function 

    movl  8(%ebp), %ecx # first argument 
    movl  12(%ebp), %edx # second argument 
           # other arguments 
           # checking last byte of string res 

回答

1

可變參數函數是C的功能,所以你可能會被檢查出如何爲架構的開源實現的va_startva_argva_end/ABI你有興趣來提供最好的服務。

您不需要類似printf函數的明確參數計數,因爲該信息嵌入格式字符串中 - 期望的可變參數的數量和類型由格式說明符的數量和詳細信息給出。

需要了解您的ABI的過程調用方面是非常嚴重的細節,以使所有這些工作正常工作。例如,浮點和整數參數是否會進入同一個堆棧,或者是否有一些傳入了寄存器?你需要什麼尺碼來促銷類型,以確保你的va_arg等價物總能在正確的時間適合正確的類型?等等...

+0

我讀了一點。似乎我不能使用寄存器作爲參數。無法找到如何去做。希望這不是太多的代碼。如果有很多論點,我不應該把它們放在寄存器裏嗎? – 2013-05-05 14:50:48

+0

如果我知道這個函數能夠使用多少個參數,那就太好了,但現在我需要確保它至少需要兩個參數,最多可以有無數個參數。 – 2013-05-05 14:56:21

+2

@KimJonatanWesselBjørneset,函數調用的寄存器和堆棧的使用由您的ABI /過程調用標準定義。如果你正在發明自己的ABI,你可以做任何你想做的事情。但請記住,您的寄存器數量有限,因此您可能需要某種方式將額外功能添加到堆棧中。 – 2013-05-05 15:01:32

1

我會做,方式如下:

你已經知道前兩個參數。下一個參數是16(%ebp),所以我會把這個地址放到一個寄存器中,並用它作爲基地址。現在我解析我的字符串,因爲這給了我需要多少個寄存器的信息。對於遇到的每個參數,從我的基址中獲取值並將其增加4,因爲下一個參數將在那裏。

我想沒有真正的需要在同一時間註冊所有參數,因爲您可能會按順序掃描formatstirng。

+0

是的,我在想這可能是一個很好的解決方案。現在嘗試在每個參數後增加四個地址。除了我不知道怎麼...嘗試addl 4(%ebp),但我運行時遇到seg故障:( – 2013-05-06 00:54:56

+0

您正在增加內存而不是註冊表。您必須執行「add 4,%reg」 – Devolus 2013-05-06 04:27:18

+0

If你不確定adressingmodes我會編寫一個簡單的C程序,並查看編譯器的輸出結果,你可以讓編譯器創建一個asm文件,你可以看看哪個是非常強大的, – Devolus 2013-05-06 04:29:46