2013-05-07 53 views
8

我編寫了一個程序用XOR交換2個變量。在C程序中解碼程序集輸出

var1 = var1^var2; 
var2 = var2^var1; 
var1 = var1^var2; 

我編譯它與其他

$ gcc Q1.c -save-temps -o Q1 

我得到這個輸出在大會形式相處大會輸出...

movl 24(%esp), %edx 
movl 28(%esp), %eax 
xorl %edx, %eax 
movl %eax, 24(%esp) 
movl 28(%esp), %edx 
movl 24(%esp), %eax 
xorl %edx, %eax 
movl %eax, 28(%esp) 
movl 24(%esp), %edx 
movl 28(%esp), %eax 
xorl %edx, %eax 

我不熟悉x86彙編但我曾參與過ARM組裝。 什麼是數字和這裏的意思?

movl 28(%esp), %edx 
movl 24(%esp), %eax 
+1

從%esp(堆棧指針)偏移24/28字節 – 2013-05-07 19:06:53

+3

這些看起來像esp(堆棧指針)的偏移量。您通常使用堆棧指針的偏移量來訪問局部變量和參數。堆棧向下增長,因此您通常使用負偏移來訪問參數,而對於局部變量使用正偏移。 – 2013-05-07 19:07:37

+3

「我編寫了一個程序,用XOR交換2個變量。」爲什麼?希望只是檢查大會。 – 2013-05-07 19:07:59

回答

9

%esp是堆棧指針。 24(%esp)地址讀取值%esp + 24

+0

和這些值之間的差異,因爲即時通訊使用整數..對嗎? – ArunMKumar 2013-05-07 19:08:27

+1

'4'的區別是因爲你的值在堆棧中長度爲4個字節。 – ouah 2013-05-07 19:09:15

+0

我厭倦了這件事,我在這兩者之間插入了另一個整數,同時聲明並初始化了它,但是這兩個結尾相鄰。在這裏工作的任何優化? – ArunMKumar 2013-05-07 19:12:34

2

這些都是偏移,你必須增加的ESP值來獲得真實地址

4

我可以很容易地看到你的困惑。有人糾正我,但我認爲這就是AT語法,以及他們究竟如何或在哪裏放置所有「%」符號和使用括號等等,編譯器編寫者可以隨心所欲地做到這一點。 (如果你不喜歡他們做了什麼,寫自己的編譯器,以及免費去做等等)

我在英特爾的語法爲你重新寫了這個。我完全忘記了他們所說的,但無論如何,在他們的語法中,目的地首先出現在指令中,而其他部分則遵循它。寄存器名稱周圍的括號表示「您可以在該寄存器指向的地址找到的東西」對於很多寄存器,您可以添加自己的偏移量,芯片將生成添加了該偏移量的地址。

警告,我認爲這是對的,但我真的應該睡在家裏了。

無論如何,看看這有助於

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
     ;             ; 
     ; Arun's Swap Via Xor Function      ; 
     ;             ; 
     ; Arun is studying C and ASM      ; 
     ;             ; 
     ; On Entry: var1 is at the 24th place in the stack ; 
     ;             ; 
     ;   var2 is at the 28th place in the stack ; 
     ;             ; 
     ;   Both of these are 32 bit numbers which ; 
     ;   is why they are 4 bytes apart   ; 
     ;             ; 
     ; On Exit: var1 is in Eax       ; 
     ;             ; 
     ;   var2 is in Edx       ; 
     ;             ; 
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 


Aruns_Swap_Via_Xor_Function: 

     MovL Edx, [Esp + 24]  ;var1 goes into Edx 
     MovL Eax, [Esp + 28]  ;var2 goes into Eax 

     XorL Eax, Edx    ;Xor them and put the result in Eax 

     MovL [Esp + 24], Eax  ;Store the result in var1 on the stack 

     MovL Edx, [Esp + 28]  ;Original var2 goes in Edx this time 

     MovL Eax, [Esp + 24]  ;The bit fiddled var1 is now in Eax 
            ;Be aware, this is not exactly optimized 
            ; but it will work, and this compiler apparently 
            ; doesn't want to take chances. 
            ; The brass tacks are that this instruction 
            ; as it appears here, is a defacto Nop 

     XorL Eax, Edx    ;Now Xor both of those values and put the result in Eax 
     MovL [Esp + 28], Eax  ;That modified value goes into var2 
            ;(Be alert, this is really the original var1) 

     MovL  Edx, [Esp + 24]  ;The original var2 is now in Edx 
     MovL  Eax, [Esp + 28]  ;The modified var2 is now in Eax 

     XorL Eax, Edx    ;Xor those two and put the result in Eax 
            ;Now Eax and Edx hold each other's original contents 
            ; 
            ;(and life goes on) 

這麼多了點。萬一你在彙編語言課程中遇到了這個問題,這個問題多年來一直讓人們(包括我)迷住了。這是你的教授可能在尋找的東西。順便說一下,事實上,你可以在互聯網上找到它,維基百科。

以前的11個指令可以減少到3說明

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
     ;             ; 
     ; A slightly optimized swap function    ; 
     ;             ; 
     ; Arun is studying C and ASM      ; 
     ;             ; 
     ; On Entry: var1 is in Eax       ; 
     ;             ; 
     ;   var2 is in Ebx       ; 
     ;             ; 
     ;   Both of these are 32 bit numbers, and ; 
     ;   so we will use 32 bit instructions. ; 
     ;             ; 
     ; On Exit: var1 is in Ebx       ; 
     ;             ; 
     ;   var2 is in Eax       ; 
     ;             ; 
     ;             ; 
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 

Slightly_Optimized_Swap_Routine: 


     XorL Eax, Ebx    ;Xor them and put the result in Ebx 
            ;At this point Eax is var1 and Ebx is weird number 

     XorL Ebx, Eax    ;Xor that result with the origial var1 
            ;At this point, Eax is var2 and Ebx is still weird number 

     XorL Eax, Ebx    ;Xor them and put the result in Ebx 
            ;At this point, Eax is var2 and Ebx is Var1 
            ; 
            ;(and life goes on) 

最後,硬件設計和微處理器來救援......

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
     ;             ; 
     ; A slightly better optimized swap function  ; 
     ;             ; 
     ; Brought to you by Clint on Stack Overflow  ; 
     ;             ; 
     ; On Entry: var1 is in Eax       ; 
     ;             ; 
     ;   var2 is in Ebx       ; 
     ;             ; 
     ;   Both of these are 32 bit numbers, and ; 
     ;   so we will use 32 bit instructions. ; 
     ;             ; 
     ; On Exit: var1 is in Ebx       ; 
     ;             ; 
     ;   var2 is in Eax       ; 
     ;             ; 
     ;             ; 
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 


Slightly_Better_Swap_Routine: 


     XchgL Eax, Ebx    ;Microprocessor magic, exchange them in one instruction. 
            ; Honest, hardware guys can do stuff like that. The previous 
            ; eleven instructions have been reduced to one. Ta-Da 
            ; 
            ;(and life goes on) 
+0

我認爲這個說法完全沒有必要:「如果你不喜歡他們做的,寫你自己的編譯器,並免費做,等等。」恕我直言。 – Jack 2013-05-08 00:49:42

+0

'xchg reg,reg'不是概念性'xchg mem,mem'的有效替代品,因爲它避開了從內存到內存的操作,而且帶有內存操作數的xchg在大多數平臺上導致鎖。而且,這些片段中有太多的評論。最後,Reverse Nolish Potation是另一回事;) – 2013-05-08 00:53:39

+0

@Jack,如果與你有廣泛的協議,我將刪除它 – 2013-05-08 01:39:02