Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7993651
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T13:55:01+00:00 2026-06-04T13:55:01+00:00

void myFunc(char dummy) { char *addrFirstArg = &dummy; } int main() { char dummy

  • 0
void myFunc(char dummy) {
    char *addrFirstArg = &dummy;
}

int main() {
    char dummy = 42;
    myFunc(dummy);
    return 0;
}

I run the above under gdb and add a breakpoint at myFunc. I step once to compute the addrFirstArg value and examine it.

I also do

info frame

to spit out information about the frame myFunc. As far as my understanding of the C stack implementation goes, I expect that addrFirstArg should be 8 bytes above the base pointer for the frame myFunc.

This is the output that I see:

(gdb) p &dummy
$1 = 0xffffd094 "*\202\f\b\032\004"

(gdb) info frame
Stack level 0, frame at 0xffffd0b0:
 eip = 0x8048330 in findStackBottom (reporter.c:64); saved eip 0x8048478
 called by frame at 0xffffd170
 source language c.
 Arglist at 0xffffd0a8, args: dummy=42 '*'
 Locals at 0xffffd0a8, Previous frame's sp is 0xffffd0b0
 Saved registers:
 ebp at 0xffffd0a8, eip at 0xffffd0ac

(gdb) x/1c 0xffffd0b0
0xffffd0b0:     42 'a'

Thus, inside the frame myFunc, ebp points to the location 0xffffd0a8, where as the address of dummy is 0xffffd094, which is 0x14 bytes below ebp, instead of being 0x8 bytes above it.

This ‘discrepancy’ disappears if I declare my dummy to be an int and myFunc to take in an int argument.

I’m really intrigued by this behavior.
It was reproducible – I ran it a bunch of times.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T13:55:03+00:00Added an answer on June 4, 2026 at 1:55 pm

    You see the differences better if you use gcc -S; in the char case we have

    char case                       int case (diffs)
    
    pushl   %ebp
    movl    %esp, %ebp
    subl    $20, %esp               subl    $16, %esp
    movl    8(%ebp), %eax           x
    movb    %al, -20(%ebp)          x
    leal    -20(%ebp), %eax         leal    8(%ebp), %eax
    movl    %eax, -4(%ebp)
    leave
    ret
    

    When the function is entered, the stack is (top on top):

    esp     return address
    esp+4   2A 00 00 00
    

    This is because the single char is “pushed” on the stack this way

    movsbl  -1(%ebp), %eax
    movl    %eax, (%esp)
    

    and the x86 is little endian.

    After the “preamble” the situation is like this

    esp            (room for local char dummy - byte 42) ...
    ...
    ebp-4          room for char *
    esp+20 = ebp   ebp
    ebp+4          return addr
    ebp+8          2A 00 00 00       
    

    The “char” (stored as 32 bit integer) is then taken from ebp+8 (the original value “pushed” by the main, but as “32 bit”) to eax and then the lower less significant byte is put in a local storage.

    The int case is simpler since we don’t need alignments and we can take “directly” the address of whatever was on the stack.

    esp             ...
    ...
    ebp-4          room for int *
    esp+16 = ebp   ebp
    ebp+4          return addr
    ebp+8          2A 00 00 00       
    

    So, in the first case (the char case), esp is decremented by 4 more bytes to hold the single char: there’s an extra local storage.

    Why this?

    As you have seen, the single char is pushed on stack as a 32bit “integer” (eax), and it is taken back in eax in the same way. This opeartion has no endianness problem.

    But, what if it would give back the address of ebp+8 for the char and the machine is no little endian? In that case, ebp+8 points to 00 00 00 2A and deferencing with *dummy would give 0, not 42.

    So, once the “fake int” is taken (operation that the CPU handles coherently whatever the endianness is) into a register, the LSByte must be put in a local storage so that its address is guaranteed to point to that char (lower byte) when deferenced. This is the reason for the extra code and the fact that the ebp+8 is not used: endianness altogether with the requirements of the address being aligned (e.g. the 2A in 00 00 00 2A in the big endian case would have an odd address.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Same as Win32: GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)(void*)(myFunc), &h); http://www.kernel.org/doc/man-pages/online/pages/man3/dlsym.3.html is not helpful.
I wrote a function along the lines of this: void myFunc(myStruct *&out) { out
I want to perform the operation stated above. void myFunc(void *parameters) { myObject myObj
I would like to perform the operation stated above. void myFunc() { ... //
I have the following classes: class A { public: virtual void myfunc(unsigned char c,
For this non-variadic example: int Func1(); double Func2(); void MyFunc( int, double ); int
If I am using a CString like this: void myFunc(char *str) { CString s(str);
I have this piece of code: private void myFunc(){ obj = doSomething(); //If value
I have a section of code that can be summarised as follows; void MyFunc()
Imagine I have a template function like this: template<typename Iterator> void myfunc(Iterator a, typename

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.