8

我编写了一个程序来使用 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 汇编。数字2428在这里是什么意思?

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

4 回答 4

9

%esp是堆栈指针。24(%esp)读取地址%esp+ 24 处的值。

于 2013-05-07T19:06:52.160 回答
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)
于 2013-05-08T00:36:16.197 回答
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

改为查看 intel 语法

于 2013-05-07T20:11:46.277 回答
2

这些是偏移量,您必须添加到 esp 的值才能获得真实地址

于 2013-05-07T19:07:33.220 回答