2015-04-19 37 views
0

所以我一直在研究一个问题(并且在你问之前,是的,这是作业,但我一直在付出忠实的努力!)我有一些汇编代码,想成为能够把它(尽可能忠实地)转换为C.在程序集中存储局部变量

下面是汇编代码:

A1: 
pushl %ebp 
movl %esp, %ebp 
subl $16, %esp 
movl $0, -4(%ebp) 
jmp .L2 
.L4: 
movl -4(%ebp), %eax 
sall $2, %eax 
addl 8(%ebp), %eax 
movl (%eax), %eax 
cmpl 12(%ebp), %eax 
jg .L6 
.L2: 
movl -4(%ebp), %eax 
cmpl 16(%ebp), %eax 
jl .L4 
jmp .L3 
.L6: 
nop 
.L3: 
movl -4(%ebp), %eax 
leave 
ret 

而且这里的一些C代码的我写模仿它:

int A1(int a, int b, int c) { 
    int local = 0; 
    while(local < c) { 
     if(b > (int*)((local << 2) + a)) { 
      return local; 
     } 
    } 
return local; 
} 

我有几个关于如何的问题装配作品。 首先,我注意到在L4中while循环的主体没有任何东西被分配给本地。它在函数开始时被初始化为0,然后再也不会被修改。看看我为它编写的C代码,虽然这看起来很奇怪,但考虑到如果if条件失败,循环将无限期地继续。我在那里错过了什么?我是你需要的代码就像一个片段的印象是:

movl %eax, -4(%ebp) 

,以实际分配任何局部变量,而我没有看到这样的事情在while循环的主体。其次,你会看到在汇编代码中,唯一声明的局部变量是“local”。因此,我不得不使用的类似的代码片段:

if(b > (int*)((local << 2) + a)) 

这条线的输出不会看起来很像汇编代码,不过,我想我可能犯了一个错误。我在这里做错了什么?

最后(感谢您的耐心等待!),在相关说明中,我明白在while循环中此if循环的目的是在条件满足时触发,然后返回本地。因此L6和“nop”(基本上什么也不说)。但是,我不知道如何在我的程序中复制这些内容。我已经尝试过“休息”了,我试着回到本地,就像你在这里看到的那样。我理解这些功能 - 我只是不知道如何在C中复制它(尽管使用goto很短,但这样做会影响练习的目的......)。

谢谢你的时间!

+0

C代码中的循环将无限运行或在第一次迭代期间返回,具体取决于if条件是否为真,因为它不更新任何变量。 – Barmar

+0

@Barmar我知道。我试图模仿汇编代码,就像我说的,我没有看到汇编代码在哪里更新本地变量。 :L –

回答

0

这是我的猜想:

int A1 (int *a, int value, int size) 
{ 
    int i = 0; 

    while (i<size) 
    { 
    if (a[i] <= value) 
     break; 
    } 
    return i; 
} 

其中,编译回装配,使我这个代码:

A1: 
.LFB0: 
     pushl %ebp 
     movl %esp, %ebp 
     subl $16, %esp 
     movl $0, -4(%ebp) 
     jmp  .L2 
.L4: 
     movl -4(%ebp), %eax 
     leal 0(,%eax,4), %edx 
     movl 8(%ebp), %eax 
     addl %edx, %eax 
     movl (%eax), %eax 
     cmpl 12(%ebp), %eax 
     jg  .L2 
     jmp  .L3 
.L2: 
     movl -4(%ebp), %eax 
     cmpl 16(%ebp), %eax 
     jl  .L4 
.L3: 
     movl -4(%ebp), %eax 
     leave 
     ret 

现在,这似乎是等同于原来的ASM代码,只需将代码从L4开始并不相同,但是如果我们对两个代码进行排序:

ORIGINAL

movl -4(%ebp), %eax ;EAX = local 
sall $2, %eax    ;EAX = EAX*4 
addl 8(%ebp), %eax  ;EAX = EAX+a, hence EAX=a+local*4 

ASM-C-ASM

movl -4(%ebp), %eax ;EAX = i 
leal 0(,%eax,4), %edx ;EDX = EAX*4 
movl 8(%ebp), %eax  ;EAX = a 
addl %edx, %eax  ;EAX = EAX+EDX, hence EAX=a+i*4 

两个码继续

movl (%eax), %eax 

正因为如此,我想a实际上是一个指针,它指向使用4个字节的一些变量类型。通过比较第二个参数和从内存中读取的值,我猜这种类型必须是intlong。我仅仅通过方便选择int

当然这也意味着这个代码(和原始代码)没有任何意义。它在某个地方缺少i++部分。如果是这样,那么a是一个数组,第三个参数是数组的大小。我已经命名了我的本地变量i以符合像这样命名索引变量的传统。

此代码将扫描搜索其内部值等于或小于value的数组。如果找到它,则返回该值的索引。如果不是,则返回数组的大小。

+0

非常有帮助,谢谢。我会彻底研究这个! :) –

相关问题