在大会指针 [英] Pointers in Assembly

查看:133
本文介绍了在大会指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在从我的课本练习题的麻烦。
我必须填写如下所示的C code的缺失部分:

  INT转换3(INT * P1,为int * P2,INT动作)
{
    INT结果为0;
    开关(动作){
    情况1:
     // 填写
    案例2:
     // 填写
    默认:
     // 填写
}
     返回结果;
}

我在遇到麻烦的原因是因为使用指针的。我是pretty肯定,我知道他们是如何工作的,但让我详细说明。
这本书给了我们以下IA32组装与我的评论的注解。

 参数:在P1的%ebp + 8,在P2的%ebp + 12,在行动的%ebp + 16
 寄存器:导致EDX%(初始化为-1)的跳转目标:.L13 //壳体(1)
  MOVL 8(EBP%),%EAX // EAX = P1
  MOVL(%EAX),EDX%//结果= P1 *
  MOVL 12(%EBP),ECX%ECX // = P2
  MOVL(ECX%),%EAX // EAX = * P2
  MOVL 8(EBP%),ECX%ECX // = P1
  MOVL%EAX(%ECX)// * P1 = P2 *

因此​​,在结束时,它是结果= * p1和
                     * P1 = P2 *
我认为这是正确的,但接下来会发生什么是什么的困惑我。

  // .L14案(2)
   MOVL 12(%EBP),%EDX //导致= P2这是不可能的,因为p2的是一个指针和结果是int
   MOVL(%EDX),EAX%
  MOVL%EAX,EDX%
  MOVL 8(EBP%),ECX%
  ADDL(ECX%),EDX%
  MOVL 12(%EBP),EAX%
  MOVL%EDX,(%EAX)
  JMP .L19 .L19 //默认
    MOVL%EDX,EAX%

任何人都可以清除此为我?


解决方案

  // .L14案(2)
  MOVL 12(%EBP),%EDX //导致= P2这是不可能的,因为
                       // P2是一个指针,结果是int

您的评论结果= P2 是错误的。 EDX 不依赖于结果在函数的整个过程。你所知道的唯一的事情是,函数退出之后,结果存储在 EDX
(此外,尽管没有直接关系你的问题,装配有没有超越其尺寸类型的概念,所以寄存器不知道它是否拥有一个指针或int)。

所以:

  // .L14案(2)
  MOVL 12(%EBP),EDX%EDX // = P2
  MOVL(%EDX),%eax中// EAX = * P2
  MOVL%EAX,EDX%EDX // EAX =(= * P2)
  MOVL 8(EBP%),ECX%ECX // = P1
  ADDL(%ECX),%EDX // EDX = EDX + * P1(= * P1 + * P2)
  MOVL 12(%EBP),%eax中// EAX = P2
  MOVL%EDX,(%EAX)// * P2 = EDX(= * P1 + P2 *)
  JMP .L19 //如果.L19是函数的结尾,那么你现在知道
                         //这个结果= * P1 + P2 *

I'm having trouble with a practice problem from my textbook. I have to fill in the missing parts of the C code shown below:

int switch3(int *p1, int *p2, int action)
{
    int result = 0;
    switch(action) {
    case 1:
     // Fill in
    case 2:
     // Fill in
    default:
     // Fill in
}
     return result;
}

The reason I'm having trouble is because of the use of pointers. I'm pretty sure I know how they work, but let me elaborate. The book gives us the following IA32 assembly with my annotations in comments.

Arguments: p1 at %ebp+8, p2 at %ebp+12, action at %ebp+16
 Registers: result in %edx (initialized to -1) The jump targets:

.L13 // case(1)
  movl  8(%ebp), %eax // eax = p1
  movl  (%eax), %edx  // result = *p1
  movl  12(%ebp), %ecx // ecx = p2
  movl  (%ecx), %eax   // eax = *p2
  movl 8(%ebp), %ecx  // ecx = p1 
  movl %eax, (%ecx)   // *p1 = *p2

So at the end, it is result = *p1 and *p1 = *p2 I think this is correct, but what's next is what's confusing me.

.L14 //case(2)
   movl  12(%ebp), %edx // result = p2  which is not possible because p2 is a pointer and result is an int
   movl  (%edx), %eax  
  movl   %eax, %edx
  movl    8(%ebp), %ecx
  addl (%ecx), %edx
  movl  12(%ebp), %eax
  movl  %edx, (%eax)
  jmp  .L19

 .L19 // default
    movl %edx, %eax

Could anyone clear this up for me?

解决方案

.L14 //case(2)
  movl  12(%ebp), %edx // result = p2  which is not possible because 
                       // p2 is a pointer and result is an int

Your comment result = p2 is wrong. edx is NOT tied to result for the entire duration of the function. The only thing you know is that right after the function exits, result is stored in edx. (Furthermore, even though not directly relevant to your question, assembly has no concept of types beyond their sizes, so a register doesn't know whether it holds a pointer or an int.)

So:

.L14 //case(2)
  movl  12(%ebp), %edx   // edx = p2
  movl  (%edx), %eax     // eax = *p2
  movl   %eax, %edx      // edx = eax ( = *p2 )
  movl    8(%ebp), %ecx  // ecx = p1
  addl (%ecx), %edx      // edx = edx + *p1 ( = *p1 + *p2 )
  movl  12(%ebp), %eax   // eax = p2
  movl  %edx, (%eax)     // *p2 = edx ( = *p1 + *p2 )
  jmp  .L19              // if .L19 is the end of the function, then you now know
                         // that result = *p1 + *p2

这篇关于在大会指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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