繁体   English   中英

x86-64组装到C

[英]x86-64 Assembly to C

我尝试将其转换为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;
}
   x+=8; //is this true?

x号是int * ,在您当前的目标平台上int是64位宽,即8个字节。 在汇编中,您有指向字节的原始指针,因为内存可以按字节寻址,所以add rdi,8在C中像x = (int*)(((int8_t*)x)+8); 可以缩短为++x;

如果movq (%rdi), %rdxrdx = x[0]; // or " = *x;" rdx = x[0]; // or " = *x;" ,则movq -8(%rdi), %rdxrdx = x[-1];

其余的C部分看起来未完成。

警告,扰流板正在跟随!

它将搜索x数组,直到找到零值(终止符),并以找到的最小值继续更新ret

看起来我的剧透是错误的,比较可能是另一种方式。 为了确保在调试器中运行原始的asm,并在C中运行它们,以查看它们是否执行相同的操作。 与任何冗长的讨论相比,监视调试器中的汇编程序单步执行指令,检查寄存器中的值如何演化通常还更具描述性和视觉效果。 :)抱歉,不确定,但是AT&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;
}

由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

几乎与原始装配相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM