如何將該C程序轉換爲彙編代碼?我很難理解這個過程或如何啓動它。我是新來的。任何幫助,將不勝感激!將C程序轉換爲彙編代碼
while(a!=b){
if(a > b){
a = a - b;
}
else{
b = b - a;
}
}
return a;
}
側注:假設在寄存器R0和R1中已經給出了兩個正整數a和b。
你可以留下評論,解釋你是如何做到的嗎?
如何將該C程序轉換爲彙編代碼?我很難理解這個過程或如何啓動它。我是新來的。任何幫助,將不勝感激!將C程序轉換爲彙編代碼
while(a!=b){
if(a > b){
a = a - b;
}
else{
b = b - a;
}
}
return a;
}
側注:假設在寄存器R0和R1中已經給出了兩個正整數a和b。
你可以留下評論,解釋你是如何做到的嗎?
如果您使用的是gcc
,那麼如果您的源代碼是a.c
,則可以獲得程序集爲gcc -S -o a.s a.c
。如果您使用的是Visual Studio,您可以通過選擇「反彙編」窗口進行調試。下面是Visual Studio中的輸出(I起名叫做「常用」 subrountine /功能,這就是爲什麼「共同」出現):
while(a!=b){
003613DE mov eax,dword ptr [a]
003613E1 cmp eax,dword ptr [b]
003613E4 je common+44h (0361404h)
if(a > b){
003613E6 mov eax,dword ptr [a]
003613E9 cmp eax,dword ptr [b]
003613EC jle common+39h (03613F9h)
a = a - b;
003613EE mov eax,dword ptr [a]
003613F1 sub eax,dword ptr [b]
003613F4 mov dword ptr [a],eax
}
else{
003613F7 jmp common+42h (0361402h)
b = b - a;
003613F9 mov eax,dword ptr [b]
003613FC sub eax,dword ptr [a]
003613FF mov dword ptr [b],eax
}
}
00361402 jmp common+1Eh (03613DEh)
return a;
00361404 mov eax,dword ptr [a]
}
這裏變量a
最初保存在內存中,因此是b
(dword ptr [b]
)。
教授我係統編程的教授使用他所謂的'atomic-C'作爲C和彙編之間的墊腳石。用於原子-C的規則(據我的記憶):
a = b + c;
允許a = b + c + d;
是不允許的,因爲有兩家運營商那裏。if (a < b)
,但不允許if ((a < b) && (c < d))
。因此,上述計劃將翻譯成;
label1:
if (a == b)
goto label2;
if (a < b)
goto label4;
a = a - b;
goto label3;
label4:
b = b - a;
label3:
goto label1;
label2:
return a;
我希望我得到了正確的......它已經將近二十年,因爲我最後不得不寫原子-C。現在假設上面的說法是正確的,讓我們開始將一些atomic-C語句轉換爲MIPS(假設這就是你正在使用的)程序集。由埃利奧特·弗裏施提供的鏈接,我們幾乎可以立即翻譯減法步驟:
a = a - b becomes R0 = R0 - R1 which is: SUBU R0, R0, R1
b = b - a becomes R1 = R1 - R0 which is: SUBU R1, R1, R0
我用無符號減法,由於A和B是正整數。
的比較可正是如此做:
if(a == b) goto label2 becomes if(R0 == R1) goto label2 which is: beq R0, R1, L2?
的這裏的問題是,BEQ操作碼的第三個參數是位移的PC移動。在我們完成這裏的手工組裝之前,我們不會知道這個價值。
不平等是更多的工作。如果我們離開了僞代碼指令,我們首先需要使用set on less than
操作碼,如果第一個寄存器小於第二個寄存器,那麼將其中一個放入目標寄存器。一旦我們完成了,我們可以使用branch on equal
如上所述。
if(a < b) becomes slt R2, R0, R1
goto label4 beq R2, 1, L4?
跳轉很簡單,它們只是j,然後是跳轉到的標籤。所以,
goto label1 becomes j label1
我們必須處理的最後一件事是回報。返回是通過將我們想要的值移動到特殊寄存器V0,然後在調用此函數後跳轉到下一條指令完成的。問題是MIPS沒有註冊移動命令的註冊表(或者如果它忘了它),所以我們從寄存器移動到RAM然後再移回。最後,我們使用保存返回地址的特殊寄存器R31。
return a becomes var = a which is SW R0, var
ret = var which is LW var, V0
jump RA which is JR R31
有了這些信息,程序就變成了。而且我們還可以調整,我們並不知道之前的跳躍:
L1:
0x0100 BEQ R0, R1, 8
0x0104 SLT R2, R0, R1 ; temp = (a < b) temp = 1 if true, 0 otherwise
0x0108 LUI R3, 0x01 ; load immediate 1 into register R3
0x010C BEQ R2, 1, 2 ; goto label4
0x0110 SUBU R0, R0, R1 ; a = a - b
0x0114 J L3 ; goto label3
L4:
0x0118 SUBU R1, R1, R0 ; b = b - a;
L3:
0x011C J L1 ; goto lable1
L2:
0x0120 SW R0, ret ; move return value from register to a RAM location
0xLW ret, V0 ; move return value from RAM to the return register.
0x0124 JR R31 ; return to caller
它已經將近二十年以來,我不得不做這樣的東西(現在是一個天,如果我需要組裝我只是做別人的建議,並讓編譯器完成所有繁重的工作)。我相信我一路上犯了一些錯誤,並會很樂意提供任何更正或建議。我只進入了這個冗長的討論,因爲我把OP問題解釋爲做手工翻譯 - 有人可能會在學習裝配時做的事情。
歡呼聲。
謝謝!我試圖理解編譯器,並且破譯由gcc或其他編譯器生成的彙編代碼非常痛苦!順便說一句名字很重要?我知道我說加載到寄存器,但在彙編代碼中,是說BEQ A,B,8有效嗎? – 2016-04-21 20:39:28
我假設你的意思是寄存器的名稱。如果是這樣,那麼他們確實很重要。你的彙編程序應該在'BEQ A,B,8'上拋出一個錯誤,除非你已經定義了A和B。 – thurizas 2016-04-22 14:47:09
因此,讓我明白這一點,彙編指令的所有操作數名稱都來自預定義的集合(代表寄存器)?即彙編器的任務不是將任意名稱映射到寄存器,即這是在編譯時完成的嗎? – 2016-04-22 22:15:46
我翻譯的代碼爲16位NASM彙編:
loop:
cmp ax, bx
je .end; if A is not equal to B, then continue executing. Else, exit the loop
jg greater_than; if A is greater than B...
sub ax, bx; ... THEN subtract B from A...
jmp loop; ... and loop back to the beginning!
.greater_than:
sub bx, ax; ... ELSE, subtract A from B...
jmp loop; ... and loop back to the beginning!
.end:
push ax; return A
我代替r0
和bx
用於替代ax
的r1
ORG 000H // origin
MOV DPTR,#LUT // moves starting address of LUT to DPTR
MOV P1,#00000000B // sets P1 as output port
MOV P0,#00000000B // sets P0 as output port
MAIN: MOV R6,#230D // loads register R6 with 230D
SETB P3.5 // sets P3.5 as input port
MOV TMOD,#01100001B // Sets Timer1 as Mode2 counter & Timer0 as Mode1 timer
MOV TL1,#00000000B // loads TL1 with initial value
MOV TH1,#00000000B // loads TH1 with initial value
SETB TR1 // starts timer(counter) 1
BACK: MOV TH0,#00000000B // loads initial value to TH0
MOV TL0,#00000000B // loads initial value to TL0
SETB TR0 // starts timer 0
HERE: JNB TF0,HERE // checks for Timer 0 roll over
CLR TR0 // stops Timer0
CLR TF0 // clears Timer Flag 0
DJNZ R6,BACK
CLR TR1 // stops Timer(counter)1
CLR TF0 // clears Timer Flag 0
CLR TF1 // clears Timer Flag 1
ACALL DLOOP // Calls subroutine DLOOP for displaying the count
SJMP MAIN // jumps back to the main loop
DLOOP: MOV R5,#252D
BACK1: MOV A,TL1 // loads the current count to the accumulator
MOV B,#4D // loads register B with 4D
MUL AB // Multiplies the TL1 count with 4
MOV B,#100D // loads register B with 100D
DIV AB // isolates first digit of the count
SETB P1.0 // display driver transistor Q1 ON
ACALL DISPLAY // converts 1st digit to 7seg pattern
MOV P0,A // puts the pattern to port 0
ACALL DELAY
ACALL DELAY
MOV A,B
MOV B,#10D
DIV AB // isolates the second digit of the count
CLR P1.0 // display driver transistor Q1 OFF
SETB P1.1 // display driver transistor Q2 ON
ACALL DISPLAY // converts the 2nd digit to 7seg pattern
MOV P0,A
ACALL DELAY
ACALL DELAY
MOV A,B // moves the last digit of the count to accumulator
CLR P1.1 // display driver transistor Q2 OFF
SETB P1.2 // display driver transistor Q3 ON
ACALL DISPLAY // converts 3rd digit to 7seg pattern
MOV P0,A // puts the pattern to port 0
ACALL DELAY // calls 1ms delay
ACALL DELAY
CLR P1.2
DJNZ R5,BACK1 // repeats the subroutine DLOOP 100 times
MOV P0,#11111111B
RET
DELAY: MOV R7,#250D // 1ms delay
DEL1: DJNZ R7,DEL1
RET
DISPLAY: MOVC A,@A+DPTR // gets 7seg digit drive pattern for current value in A
CPL A
RET
LUT: DB 3FH // LUT starts here
DB 06H
DB 5BH
DB 4FH
DB 66H
DB 6DH
DB 7DH
DB 07H
DB 7FH
DB 6FH
END
嘗試在這裏執行你的代碼。只需將它複製到主函數中,在while
循環之前定義變量a
和b
,您就可以輕鬆完成任務。
您可以看到如何將代碼編譯爲程序集並進行大量解釋,然後才能在假設的CPU內執行彙編代碼。
使用C編譯器選項生成彙編代碼。 – 2014-09-29 02:11:39
閱讀以下答案:http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – 2014-09-29 02:12:25
我敢打賭,你正在使用的課程是使用MIPS程序集。你不會找到許多熟悉MIPS的專業人士。只要學習它。 – OregonTrail 2014-09-29 02:13:11