我正在尝试将汇编代码转换回C代码,但我注意到这一个操作叫做sarq。我认为q是地址的大小,但我不知道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 :(得分:3)
andl $1, %eax //dunno what eax is but adds 1 into it
嗯... eax
低于rax
的32b部分。它不是add
,而是and
。因此,从四元值开始,只有最低有效位(b0
)将保留在eax
中。
该值与结果值xor-ed(最初为零)。
四位值通过有符号移位向右移动,但常数为正(0x00BCDEFABCDEFBBB
),因此无关紧要。否则该代码将以无限循环结束,对于负常量!在这种情况下,人类程序员会使用shr
,因此该函数适用于任何64b值。
所以整个代码计算那个长常量的奇偶校验(以非常无效的方式加上它看起来像未经优化的代码),然后将其打印为" ans#\ n",其中#为0(偶数)设定位数)或1(奇数)。
(我没有调试它,只是快速查看它,所以也许我错过了一些东西,你应该尝试调试器,它真正做到了什么。)
顺便说一句,这些评论很好,至少很容易指出你的另一个问题。如果没有他们,没有人会注意到,只有sarq
会被回答。
答案 1 :(得分:1)
sar
是算术右移。单个操作数形式将其操作数右移一个位置,用编号的符号填充最上面的位。后缀q
表示操作数是64位操作数(四字)。因此,sarq -8(%rbp)
将四字#{1}}下方的八字节右移一个位置。