在装配中理解sarl有困难

时间:2014-10-26 20:22:36

标签: assembly x86

我无法理解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

1 个答案:

答案 0 :(得分:0)

我建议用优化进行编译。未经优化的代码包含许多堆栈的多余存储,模糊了重要的指令。 不要添加到大海捞针。
现在让我们来看看该程序:

.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

如您所见,您想知道的说明完全没用,因为它们的副作用会在使用前立即被其他说明覆盖。
事实上,这是如此令人震惊,我不得不怀疑这段代码来自何处 它既可以由一个真正残暴的编译器生成,也可以是手写的垃圾 再次,使用一个好的编译器并启用优化,代码将更加明智。