x86-64组装到C [英] x86-64 Assembly to C

查看:113
本文介绍了x86-64组装到C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图将其转换为C,但是我被卡在内存地址(%rdi)的位移上了:

I tried translating this into C, but I'm stuck at the displacement of the memory address (%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

到目前为止,我已经提出了以下建议:

I've come up with following so far:

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;

可能的解决方案(等待某人确认)

Possible solution (waiting for someone to confirm):

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?

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

No. x is int *, and on your current target platform int is 64 bit wide, which is 8 bytes. In assembly you have raw pointer to bytes, as memory is addressable by bytes, so the add rdi,8 is in C like x = (int*)(((int8_t*)x)+8); which can be shortened to ++x;

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

剩余的C部分看起来未完成.

The remaining C part looks unfinished.

警告,破坏者正在关注!

Warning, spoiler is following!

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

it will search through the x array until zero value is found (terminator), and keep updating ret with smallest value found.

看起来我的扰流板是错误的,比较可能是另一种方式.为了确保在调试器中运行原始的asm,并在您的C中运行,以查看它们是否执行相同的操作.与任何冗长的讨论相比,监视调试器中的汇编程序单步执行指令,检查寄存器中的值如何演化通常还更具描述性和视觉效果. :)抱歉,不确定,但是AT& T语法使我发疯.

And it looks like my spoiler was wrong, the compare is probably the other way. Just to make sure, run both original asm in debugger, and your C, to see if they do the same thing. Also watching assembly in debugger single-stepping over instructions, checking how values in registers evolve, is often lot more descriptive and visual, than any long discussion. :) Sorry for not being sure, but the AT&T syntax is driving me nuts.

顺便说一句,我的"C"翻译可能看起来像这样(假设asm在数组中搜索"max"值,而不是"min"(我仍然只有90%的把握)):

BTW, my "C" translation would look probably like this (let's say the asm is searching for "max" value in array, not "min" (I'm still only ~90% sure)):

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):

Which gets translated by gcc v7.2 as (I had to change the int to int64_t to have 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

与原始程序集几乎相同.

Which is almost identical to original assembly.

这篇关于x86-64组装到C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆