user1514815
user1514815

Reputation: 13

C push & pop test

Could someone please help me understand what the push_test() and pop_test() methods are attempting to test? These methods are attempting to test something and I can't figure out what that is.

The following code is written in c:

int push_test() {
    int ret_val;
    /* movl %esp, %eax    ;; save stack pointer
       pushl %esp         ;; push stack pointer onto stack
       popl %edx          ;; pop the stack into %edx
       subl %edx, %eax    ;; subtract the two values
       movl %eax, ret_val ;; set up the return value
    */
    asm("movl %%esp, %%eax; pushl %%esp; popl %%edx; subl %%edx, %%eax; movl %%eax, %0"
          : "=r" (ret_val)
          : /* no input */
          : "%edx", "%eax");
    return ret_val;
 }

int pop_test() {
  int ret_val = 0xffffffff;  /* -1 in decimal */
  /* pushl ret_val       ;; save ret_val on the stack
     movl %esp, %edx     ;; save the stack pointer
     popl %esp           ;; pop stack into the stack pointer
     movl %esp, ret_val  ;; set the popped value as the return value
     movl %edx, %esp     ;; restore original stack pointer
  */
  asm("pushl %1; movl %%esp, %%edx; popl %%esp; movl %%esp, %0; movl %%edx, %%esp"
      : "=r" (ret_val)
      : "r" (ret_val)
      : "%edx");
  return ret_val;
}

int main() {
  printf("push test: %d\n", push_test()); 
  printf("pop test: %d\n", pop_test()); 
}

/* Output:
  push test: 0
  pop test: -1
*/

Upvotes: 1

Views: 1669

Answers (1)

Hans Z
Hans Z

Reputation: 4744

Your push_test() and pop_test() is saving the stack state, destroying the stack frame, and then doing an operation based on values on the stack.

Let's go through each instruction of pop_test() and figure out what it does (push_test() is very similar in operation).

pushl ret_val pushes -1 onto the stack, incrementing the stack pointer (%esp), so right now your stack looks like: {-1}.

movl %esp, %edx copies your stack pointer into %edx, so %edx contains the memory address of position 1 on the stack, so right now your stack looks like : {-1}, %esp: stack[1], %edx : stack[1]

popl %esp pops -1 and stores it into %esp, so the stack looks like: {}, %esp: -1, %edx:stack[1]

movl %esp, ret_val takes the value of %esp, currently -1, and moves it into ret_val, so ret_val becomes -1.

finally movl %edx, %esp puts the value of %edx back in %esp and returns -1.


This method always returns -1. The idea is to push a value onto the stack, pop it back off, and see if the value stays the same. It also destroys and reforms the stack (by temporarily destroying and then restoring %esp). I would guess this is probably some learning assembly kind of deal and not an actual testing method.

Upvotes: 2

Related Questions