2012-03-21 156 views
0

我得到了這個工作,大家都謝謝!C彙編編程

我有一門功課編寫與bigmult.c

C程序應該乘兩個無符號的十六進制數一起我的C程序轉至彙編程序mulq.s。我已經開始了,但我想我需要很多幫助。這是組裝的介紹,所以它不是很長。

以下是完整的問題:

請你寫稱爲 big_mult.c相乘兩個無符號整數,x和y,從 在命令行中讀取一個C程序。輸出是一對無符號整數 ,表示完整的128位乘積x * y的最重要和最不重要的64位。輸入和輸出將以十六進制格式以 給出。你的C程序將負責讀取 輸入並打印輸出,但它會調用一個函數mull.s來實現 的實際乘法運算。您的C程序應該只使用int或 unsigned int變量,並且不應該執行任何算術運算。由mull.s定義的函數 應在程序main中的 之前的C中具有以下聲明。 void mull(unsigned int x,unsigned int y,unsigned int * high,unsigned int * low); 該產品的最低有效64位將被分配到 低位,並且該產品的最高有效64位將被分配爲高位 。請記住將適當的標題註釋放入您的程序集文件(普通C註釋/ * ... * /將適用於 程序集) 。 編寫該彙編程序的一種方法是在C中編寫一個類似的程序 ,使用-S選項 將其編譯爲彙編代碼,並修改生成的彙編代碼以執行所需的操作。您的最終 彙編代碼應該很短,並且應該只包含一個 乘法指令。

我開始編寫一個虛擬程序,讓代碼的不重要的部分在頂部,然後我完全失去了做什麼。我有pushq指令來推送%rbp並將地址移動到%rsp。在這之後我該怎麼做?

任何提示將受到歡迎!

我迄今爲止代碼:

.section __TEXT,__text,regular,pure_instructions 
    .globl _main 
    .align 4, 0x90 
_main: 
    pushq %rbp 
    movq %rsp, %rbp 

我的C程序:

#include <stdio.h> 
void mull(unsigned int x, unsigned int y, unsigned int* high, unsigned int* low); 
int main(int argc, char* argv[]) { 
    unsigned long long int x, y; 
    if(argc != 3) 
     printf("Usage: bigmult x1 x2 <where x1 and x2 are hexadecimal integers>\n"); 
    else { 
     sscanf(argv[1], "%x", &x); 
     sscanf(argv[2], "%x", &y); 
     printf("%x x %x = ", x, y); 
     mull(x, y, &x, &y); 
    } 
    return 0; 
} 
+0

您是否按照給出的建議嘗試過? – 2012-03-21 20:33:43

+6

'編寫這個彙編程序的一種方法是在C中編寫一個類似的程序,使用-S選項將其編譯爲彙編代碼,並修改生成的彙編代碼以執行所需的操作。「這是一個很好的起點。 – 2012-03-21 20:34:43

+1

我可以更直率嗎?請**執行建議**。編寫一個處理所有事情的C程序,無需任何彙編程序。然後使用由-S生成的輸出。你幾乎可以得到任何你在'免費'掙扎的東西。 – gbulmer 2012-03-21 20:39:16

回答

2

我很想添加自己的評論,但該#* & $%計算器規則不允許我做評論,直到!我有2800萬個信用點(可能少一點)。

首先,你想盡可能簡單地用C編寫你的mull()函數。如果你使用兩個32位整數(可能只是'int',但取決於你的平臺),結果代碼會更簡單(更簡單)。如果你這樣做,從你的教授的評論來看,這應該歸結爲一個32位* 32位= 64位乘法的乘法指令。如果你使用64位整數作爲你的輸入,你的CPU上可能沒有64位* 64位= 128位指令,但即使它對於你的任務來說是過度的。如果沒有,那麼編譯器會發出一系列指令來執行64位* 64位= 128位的乘法運算,這使得您很難理解正在發生的事情。

當您將單獨的C文件構建到與main()的目標文件鏈接的目標文件&時,您想要執行的操作是獲取其反彙編&尋找multiply指令。一旦找到它,向後追蹤以找出它的參數來自哪裏......它們可能位於寄存器中,也可能位於堆棧中的內存位置,具體取決於系統的ABI。然後向前追蹤,直到函數返回,看看返回給調用者的乘法結果在哪裏。

您將需要在mult()的程序集版本中複製該功能,但出現以下異常:C代碼編譯版本可能包含一些很好的序言和尾聲指令,這些指令在函數中不需要這與mult()一樣簡單。但是除非編譯器真的非常擅長優化,否則它不會注意到這一點,編譯結果可能只有它真正需要的八倍。從你的教授的評論中,你的整個mult()組裝函數甚至可能總共只有2到6條指令......並且取決於你的ABI,你可能甚至可能不需要使用堆棧。 (對於x86,您將會,但對於PowerPC或其他RISC機器,您不需要這麼簡單的功能,因爲對於許多RISC機器,只有幾個參數的函數可以將所有參數傳遞到寄存器中,因此它們不需要。堆棧的話)

因此,假設你需要使用堆棧,你的函數可能看起來是這樣的:

_mult: 
    ...instructions to move parameters from stack locations into registers... 
    ...multiply instruction using those registers... 
    ...instructions to move the results into the appropriate stack locations 
     for return values (or return value registers, depending on your ABI)... 
    ...and finally, your processor's "return" instruction 

...共計也許最多6個指令。