Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Old versions of C had implicit types for variables and functions, and this code makes use of that and some other stuff. It also was very lax about actually returning values.</p> <pre><code>main(i) // i is implicitly an integer (the default type for old C), and normally named argc // int main(int i) or void main(int i) { // The stack (which lives in high memory but grows downward) has any arguments and // probably the environmental variables and maybe even other (possibly blank/filler) // stuff on it in addition to the return address for whatever called main and possibly // the argument i, but at this point that could either be on the stack just under the // return address or in a register, depending on the ABI (application binary interface) // extern int gets(int) or extern void gets(int) // and sizeof(int) is probably sizeof(char *) gets(&amp;i); // By taking the address of i even if it wasn't on the stack it will be pushed to // it so that it will have an address (some processors have addressable registers // but they are rarely used by C for many reasons that I won't go into). // The address of i is either also pushed onto the stack or put into a register // that the ABI says should be used for the first argument of a function, and // and then a call is made to gets (push next address to stack; jump to gets) // The function gets does what it does, but according to the ABI there are // some registers that it can do whatever it wants to and some that it must // make sure are the same as they were before it was called and possibly one // or more where it is supposed to store a return value. // If the address of i was passed to it on the stack then it probably would be // restricted from changing that, but if it was passed in a register it may // have just been luckily left unchanged. // Another possiblity is that since gets returns the string address it was // passed is that it returns that in the same location as the first argument // to functions is passed. puts(); // Since, like gets, puts takes one pointer argument it will be passed this // this argument in the same way as gets was passed it's argument. Since we // were somehow lucky enough for gets to not overwrite the argument that we // passed to it and since the C compiler doesn't think it has anything new to // pass to puts it doesn't change any registers' values or do too much to the // stack. This leaves us in the situation where puts is called with the stack // and registers set up in the same way as they would be if it were passed the // address of i, just the same as gets. // The gets call with the stack variable's address (so an address high on the stack) // could have left main's return address intact, but also could have overwritten it // with garbage. Garbage as main's return address would likely result in a jump to // a random location (probably not part of your program) and cause the OS to kill the // program (possibly with an unhandled SIGSEGV) which may have looked to you like a // normal exit. Since puts appended a '\n' to the string it wrote and stdout is // line buffered by default it would have been flushed before returning from puts // even if the program did not terminate properly. } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload