I write a program to swap 2 variables using XOR.
var1 = var1 ^ var2;
var2 = var2 ^ var1;
var1 = var1 ^ var2;
I Compile it to get the Assembly Output along with others
$ gcc Q1.c -save-temps -o Q1
I Get this Output in the Assembly form...
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
I am not Familiar with x86 assembly but i have worked on ARM assembly. what does the numbers 24 and 28 mean here?
movl 28(%esp), %edx
movl 24(%esp), %eax
%esp
is the stack pointer. 24(%esp)
reads the value at address %esp
+ 24.
I can easily see your confusion. Somebody correct me, but that is AT&T syntax, I think, and exactly how or where they put all the "%" signs and used parenthesis and so on, well, compiler writers can do as they please. (If you don't like what they did, write your own compiler; and do it for free and so on.)
I have re-written this in Intel syntax for you. I forget exactly what they call it, but anyway, in the their syntax the destination comes first in the instruction, and the other parts follow it. Brackets around a register name mean "The stuff which you will find located at the address to which this register points" With a lot of the registers, you can add your own offset, and the chip will generate the address with that offset added in.
Caveat, I think this is right, but I really should be home asleep by now.
Anyway, see if this helps
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; 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)
So much for that. Just in case you are facing this in some assembly language course, this problem has fascinated people (including me) for years. Here's what your professors are probably looking for. By the way, you can find this on the internet, wikipedia, in fact.
The previous 11 instructions can be reduced to 3 instructions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; 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)
Finally, hardware designers and microprocessors to the rescue...
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; 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)
I recommend looking through Programming Ground Up ( x86 assembly , GAS syntax)
http://gnu.mirrors.pair.com/savannah/savannah//pgubook/ProgrammingGroundUp-1-0-booksize.pdf
you can also try this
gcc -S -masm=intel test.c
to view intel syntax instead
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With