2016-09-11 47 views
0

我想将汇编代码转换回C代码,但我注意到这一个操作称为sarq。我认为q是地址的大小,但我不知道sarq对地址做了什么。我评论了我相信代码的作用。汇编语言 - sarq在代码中做了什么?

.LC0 .string "ans %d\n" 
main: 
.LFB0:     val = -8(%rbp), result = -12(%rbp) 
     pushq %rbp 
     movq %rsp, %rbp 
     subq $16, %rsp 
     movabsq $53162464113523643, %rax 
     movq %rax, -8(%rbp)  //val(variable) address -8,inputs value in %rax 
     movl $0, -12(%rbp)  //result(variable) address -12, inputs 0 
     jmp  .L2   //starts loop 
.L3: 
     movq -8(%rbp), %rax  //moves value in val into rax 
     andl $1, %eax  //dunno what eax is but adds 1 into it 
     xorl %eax, -12(%rbp)  //compares the value of eax and result to see if they are not equal. so compares 1 to 0 
     sarq -8(%rbp)  //does something to val? 
.L2: 
     cmpq $0, -8(%rbp)  //compares val to 0 
     jg  .L3   //if greater, goes to L3 
     movl -12(%rbp), %eax  //else, moves value from result into eax 
     movl %eax, %esi  //moves eax into esi 
     movl $.LC0, %edi  //Moves w/e $.LC0 is into edi. Based on the top, edi now holds that string? 
     movl $0, %eax  //moves 0 into eax 
     call printf   //print statement 
     leave 
     ret 
+0

[SAR记录在英特尔的insn set ref手册中](http://www.felixcloutier.com/x86/SAL:SAR:SHL:SHR.html)。另请参阅http://stackoverflow.com/tags/x86/info –

回答

1

sar是一种算术右移。单一操作数形式将其操作数右移一位,用数字符号填充最高位。后缀q指示操作数是64位操作数(四字)。因此sarq -8(%rbp)%rbp以下的八字节右移一位。

+0

所以我会将该顶部数字转换为二进制数字,将其转换为1并将其添加到0的前面?因此,如果结果!= 1,那么操作将会结束? –

+0

@JMei:b63(最高位)保持它的值(符号)。对于位b62至b0,右移一位表示b_i = b_old_i + 1。所以0xAAAAAAAAAAAAAAAA将变成0xD555555555555555。 'shr'会填满b63零。 'sal'和'shl'都会左移数值(相同的结果)。 'sarq'几乎被整数除法,除了'sar(-1)== -1'。为什么不简单检查x86指令集参考指南,然后搜索一些位移指令的教程?如果你想要任何东西,你应该有指令集ref。无论如何。 :) – Ped7g

3

andl $1, %eax //dunno what eax is but adds 1 into it

Uhmm ... eaxrax下32B的一部分。它不是add,而是and。因此,从四位值只有最低有效位(b0)将保留在eax

这是一个带结果值(最初为零)的异或。

四值通过有符号移位向右移动,但常数为正值(0x00BCDEFABCDEFBBB),所以无所谓。否则,该代码将以无限循环结束,对于负常数!在这种情况下,人类程序员将使用shr,所以该函数将适用于任何64b值。

因此,整个代码计算该长常量的奇偶校验(以相当无效的方式,再加上它看起来像未优化的代码),然后将其打印为“ans#\ n”,其中#为0(即使计数为“ )或1(奇数)。 (我没有调试它,只是快速查看它,所以也许我错过了一些东西,你应该尝试在调试器中,它真的做了什么)。


顺便说一句,这些评论很好,至少很容易指出你的另一个问题。没有他们没有人会注意到,只有sarq将被回答。