Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
620 views
in Technique[技术] by (71.8m points)

c - Pointers in Assembly

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
.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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...