2009-11-07 60 views
2

我需要將該方法中評論的內容翻譯成彙編程序。我有一個大致的想法,但不能。將FOR轉換爲彙編程序

任何人都可以幫助我嗎?是英特爾X32架構:

int 
secuencia (int n, EXPRESION * * o) 
{ 
    int a, i; 
//--- Translate from here ... 
    for (i = 0; i < n; i++){ 
    a = evaluarExpresion(*o); 
    o++; 
    } 
    return a ; 
//--- ... until here. 
} 

翻譯的代碼必須__asm之內:

__asm { 
     translated code 
} 

謝謝

最後更新:

這是最後的版本,工作並表示感謝所有的幫助:)

int 
secuencia (int n, EXPRESION * * o) 
{ 
    int a = 0, i; 
    __asm 
    { 
     mov dword ptr [i],0    ; int i = 0 
     jmp salto1 
     ciclo1: 
     mov eax,dword ptr [i]   
     add eax,1      ; increment in 1 the value of i 
     mov dword ptr [i],eax   ; i++ 
     salto1: 
     mov eax,dword ptr [i]   
     cmp eax,dword ptr [n]   ; Compare i and n 
     jge final      ; If is greater goes to 'final' 
     mov eax,dword ptr [o] 
     mov ecx,dword ptr [eax]   ; Recover * o (its value) 
     push ecx      ; Make push of * o (At the stack, its value) 
     call evaluarExpresion   ; call evaluarExpresion(* o) 
     add esp,4      ; Recover memory from the stack (4KB corresponding to the * o pointer) 
     mov dword ptr [a],eax   ; Save the result of evaluarExpresion as the value of a 
     mov eax,dword ptr [o]   ; extract the pointer to o 
     add eax,4      ; increment the pointer by a factor of 4 (next of the actual pointed by *o) 
     mov dword ptr [o],eax   ; o++ 
     jmp ciclo1      ; repeat 
     final:       ; for's final 
     mov eax,dword ptr [a]   ; return a - it save the return value at the eax registry (by convention this is where the result must be stored) 
    } 
} 
+3

這是功課嗎?如果是這樣,不要指望有人給你答案。顯示你到目前爲止。 – 2009-11-07 22:16:39

+2

爲什麼你需要這樣做?編譯器完全可以爲你做到這一點。編譯器輸出有沒有足夠的理由? – 2009-11-07 22:18:42

+2

讓'gcc'爲你做功課要比問一個編程問答網站要快。試試'man gcc'。 – 2009-11-07 22:22:02

回答

8

從本質上講,在彙編語言中,嚴格來說,沒有循環的概念,就像使用更高級的語言一樣。它全部通過跳轉來實現(例如,作爲「goto」...)

也就是說,x86有一些指令,假設您將編寫「循環」,隱式使用寄存器ECX作爲循環計數器。

一些例子:

mov ecx, 5   ; ecx = 5 
.label: 
    ; Loop body code goes here 
    ; ECX will start out as 5, then 4, then 3, then 1... 
    loop .label  ; if (--ecx) goto .label; 

或者:

jecxz .loop_end ; if (!ecx) goto .loop_end; 
.loop_start: 
    ; Loop body goes here 
    loop .loop_start ; if (--ecx) goto .loop_start; 
.loop_end: 

而且,如果你不喜歡這種loop指令東西倒數...你可以寫類似:

xor ecx, ecx  ; ecx = 0 
.loop_start: 
    cmp ecx, 5   ; do (ecx-5) discarding result, then set FLAGS 
    jz .loop_end  ; if (ecx-5) was zero (eg. ecx == 5), jump to .loop_end 
    ; Loop body goes here. 
    inc ecx   ; ecx++ 
    jmp .loop_start 
.loop_end: 

這會更接近典型的for (int i=0; i<5; ++i) { }

+1

簡單漂亮。 :) – mrduclaw 2009-11-07 23:24:41

+0

我同意...... asveikau:這是一個非常好的解釋,現在我現在從哪裏開始。非常非常感謝你。 – Sheldon 2009-11-08 00:46:23

2

爲此,您可能會使用在每個循環處遞減ecx(通常稱爲擴展計數器)的循環指令,並在ecx達到零時熄滅。但是爲什麼還要使用內聯asm?我敢肯定那樣簡單將編譯器優化的正確的東西......

(我們說的x86架構,因爲它是基於80x86的電腦,但它是一個「OK」的錯誤= P)

+0

Jejej謝謝......我建立了幾年的軟件..但現在是我開始自學PC架構,彙編程序和更多。 – Sheldon 2009-11-08 00:57:23

5

使用GCC來生成彙編代碼

gcc -S -c sample.c 

人GCC是你的朋友

+5

或者:man,gcc是你的朋友! LOL,一種生成彙編語言的編譯器。有誰會想過。 – 2009-11-07 22:28:46

+0

哈哈,海灣合作委員會的手冊頁可能會有用,但請注意,海灣合作委員會的手冊頁是12,838行! 「-S」選項甚至不會顯示,直到678行! – poundifdef 2009-11-07 22:54:06

+0

@rascher不得不閱讀?消滅思想!正則表達式兼容搜索?異端! ;) – mrduclaw 2009-11-07 23:21:06

6

注意

for (init; cond; advance) { 
    ... 
} 

本質上是

init; 
while(cond) { 
    ... 
    advance; 
} 

這應該很容易翻譯成彙編語言,如果你已經支付任何關注類語法糖。

+0

謝謝,所以我可以使用註冊表...遞減和跳躍...嗯,現在我有一個形狀 – Sheldon 2009-11-08 00:44:52