我编写了一个程序来使用XOR交换2个变量。
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程序集。 24 和 28 的数字在这里意味着什么?
movl 28(%esp), %edx
movl 24(%esp), %eax
答案 0 :(得分:9)
%esp
是堆栈指针。 24(%esp)
读取地址%esp
+ 24.
答案 1 :(得分:4)
我很容易看出你的困惑。有人纠正我,但我认为这是AT& T语法,以及他们如何或在何处放置所有“%”符号并使用括号等等,好吧,编译器编写者可以随心所欲。 (如果你不喜欢他们所做的,那就编写你自己的编译器;免费试用它等等。)
我已经为您重写了Intel语法。我完全忘记了他们所谓的内容,但无论如何,在他们的语法中,目标首先出现在指令中,而其他部分则遵循它。寄存器名称周围的括号表示“您将找到位于该寄存器指向的地址的东西”。对于许多寄存器,您可以添加自己的偏移量,芯片将生成添加了该偏移量的地址。
警告,我认为这是对的,但我现在应该回家睡觉了。无论如何,看看这是否有帮助
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; 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)
答案 2 :(得分:3)
我建议查看Programming Ground Up(x86汇编,GAS语法)
http://gnu.mirrors.pair.com/savannah/savannah//pgubook/ProgrammingGroundUp-1-0-booksize.pdf
你也可以试试这个
gcc -S -masm=intel test.c
来查看英特尔语法
答案 3 :(得分:2)
这些是抵消,您必须添加esp的值才能获得真实地址