我尝试将其翻译成C语言,但我仍然坚持使用内存地址(%rdi
)的位移:
program:
movq (%rdi), %rax
testq %rax, %rax
je L1
addq $8, %rdi
movq %rax, %rdx
L3:
cmpq %rdx, %rax
cmovl %rdx, %rax
addq $8, %rdi
movq -8(%rdi), %rdx
testq %rdx, %rdx
jne L3
L1:
ret
到目前为止,我已经提出了以下建议:
int func(int *x){
int ret = *x;
if(ret != 0){
x+=8; //is this true?
y = ret;
while(y!=0){
if(ret<y){
ret = y;
}
y=?? //What should this say?
}
}
return ret;
可能的解决方案(等待某人确认):
int func(int *x){
int ret = *x;
if(ret!=0){
++x;
int y = ret;
while(y != 0){
if(ret < y){
ret = y;
}
++x;
y = x[-1];
}
}
return ret;
}
答案 0 :(得分:2)
x+=8; //is this true?
没有。 x
为int *
,在您当前的目标平台int
上为64位宽,即8个字节。在汇编中你有指向字节的原始指针,因为内存可以按字节寻址,所以add rdi,8
在C中就像x = (int*)(((int8_t*)x)+8);
一样可以缩短为++x;
如果movq (%rdi), %rdx
为rdx = x[0]; // or " = *x;"
,则movq -8(%rdi), %rdx
为rdx = x[-1];
剩下的C部分看起来未完成。
警告,扰流器正在跟随!
它将搜索
x
数组,直到找到零值(终结符),并继续更新ret
找到最小值。
看起来我的扰流板错了,比较可能是另一种方式。只是为了确保在调试器中运行原始asm和你的C,看它们是否做同样的事情。同时观察调试器中的汇编单步执行指令,检查寄存器中的值如何演变,通常比任何长时间的讨论更具描述性和可视性。 :)很抱歉不确定,但AT&amp; T语法让我疯狂。
顺便说一下,我的“C”翻译看起来可能就像这样(假设asm正在搜索数组中的“max”值,而不是“min”(我仍然只有90%肯定)):int64_t func(int64_t *x) {
if (0 == *x) return 0;
int64_t ret = *x;
do {
if (ret < *x) ret = *x;
++x;
} while (0 != *x);
return ret;
}
哪个得到translated by gcc v7.2(我必须将int
更改为int64_t
才能拥有64b int
):
func(long*):
movq (%rdi), %rax
testq %rax, %rax
je .L1
movq %rax, %rdx
.L3:
cmpq %rdx, %rax
cmovl %rdx, %rax
addq $8, %rdi
movq (%rdi), %rdx
testq %rdx, %rdx
jne .L3
.L1:
rep ret
这与原始装配几乎完全相同。