【问题标题】:Having trouble understanding sarl in assembly在汇编中无法理解 sarl
【发布时间】:2014-10-28 12:55:22
【问题描述】:

我无法理解 IsPrime 函数中的循环。我主要无法理解代码中的前几行。 x86 程序集 32 位。栈大小为36,有可能是代码有错误

.L4:        #odd number
movl    8(%ebp), %eax               #move arg(odd number) into eax
movl    %eax, -28(%ebp)             
movl    $1431655766, -32(%ebp)      #having trouble understanding this line
movl    -32(%ebp), %edx
imull   -28(%ebp)                                     
movl    %edx, %ecx
movl    -28(%ebp), %eax
sarl    $31, %edx                   #and what this does
movl    %ecx, %edx
subl    %eax, %edx
movl    %edx, -24(%ebp)
movl    -24(%ebp), %eax
addl    %eax, %eax
addl    -24(%ebp), %eax
movl    -28(%ebp), %ecx
subl    %eax, %ecx
movl    %ecx, -24(%ebp)
cmpl    $0, -24(%ebp)
jne .L7
cmpl    $3, 8(%ebp)
jne .L6

【问题讨论】:

  • 如果是家庭作业,而“A. Bhattacharjee”是你的老师,那么兄弟,你有麻烦了!

标签: assembly x86


【解决方案1】:

我建议使用优化进行编译。未优化的代码在堆栈中包含许多多余的存储,从而掩盖了重要的指令。 不要大海捞针。
现在让我们看一下程序:

.L4:        #odd number
movl    8(%ebp), %eax            #move arg to eax register, which is an implicit
                                 #operand of multiplication operations
movl    %eax, -28(%ebp)          #store arg to a local variable
movl    $1431655766, -32(%ebp)   #store an immediate value to a local variable
                                 #not terribly useful but OK
movl    -32(%ebp), %edx          #move local variable into edx before imul???
                                 #completely useless.
imull   -28(%ebp)                #imull calculates 64bit result of eax*local_var
                                 #which is the same as eax, so eax*eax
                                 #and stores the result in edx:eax, so the
                                 #previous write to edx is
                                 #unconditionally overwritten
movl    %edx, %ecx               #store high 32bits of the mul to ecx, OK
movl    -28(%ebp), %eax          #reload eax from stack var, OK
sarl    $31, %edx                #shift right by 31 arithmetically
                                 #(~divide by 2 to the power of 31,
                                 #preserving and extending the sign bit)
                                 #also useless due to the next instruction:
movl    %ecx, %edx               #move ecx to edx.
subl    %eax, %edx 
movl    %edx, -24(%ebp) 
movl    -24(%ebp), %eax
addl    %eax, %eax
addl    -24(%ebp), %eax
movl    -28(%ebp), %ecx
subl    %eax, %ecx
movl    %ecx, -24(%ebp)
cmpl    $0, -24(%ebp)
jne .L7
cmpl    $3, 8(%ebp)
jne .L6

如您所见,您想知道的指令完全没有用,因为它们的副作用在使用前会立即被其他指令覆盖。
事实上,这太令人震惊了,我不得不怀疑这段代码是从哪里来的。
它可能是由真正残暴的编译器生成的,也可能是手写垃圾。
同样,使用好的编译器并启用优化,代码会更加合理。

【讨论】:

    猜你喜欢
    • 2013-03-19
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多