echo and printenv in x86 Assembly

This post contains implementations of echo and printenv in 32-bit x86 assembly for Linux.

echo is a Unix utility that prints its arguments to standard output.

printenv is a Unix utility that prints the environment to standard output.

The core functionality of these programs can be written in a few lines of C, where program arguments and the environment are passed as function arguments to main.

When a process is executed on Linux (or other Unix-like systems), its stack contains pointers to the program arguments and the environment, as shown below.

        |--------------------------|     Low
0(%esp) |      Argument Count      |  Addresses
        |--------------------------|
4(%esp) |     Argument Pointers    |
        |           ...            |
        |--------------------------|
        |            0             |
        |--------------------------|
        |   Environment Pointers   |
        |           ...            |
        |--------------------------|
        |            0             |
        |--------------------------|
        |     Additional Data      |
        |           ...            |     High
        |--------------------------|  Addresses

The stack grows downward in memory. That is, the top of the stack has the lowest memory address. When a program is executed, the top of the process stack contains 1) the argument count (conventionally referred to as argc in source code), followed by 2) pointers to the argument strings, 3) zero, 4) pointers to the environment strings, 5) zero, and 6) additional data (including the data that the argument/environment pointers reference).

echo and printenv can be implemented in assembly language by traversing the stack and printing out the relevant strings.

Helper Functions

Both assembly programs have a helper macro, print, for writing to standard output. They also share a helper function, strlen, which returns the length of a string.

echo Assembly Code

The assembly code for echo iterates over the argument pointers on the stack, printing the string corresponding to each argument. The iteration starts at the second element on the stack (past the first element, argument count), and stops when reaching a zero.

The full source code for echo, including the print macro and strlen function, is available at https://gist.github.com/dstein64/890e02e8e277f17d931c8a250ceaaf44.

printenv Assembly Code

The assembly code for printenv is similar to the code above for echo, but starts iteration a few elements deeper into the stack, at the first environment variable pointer. It uses the argument count on the stack to jump past the argument pointers.

The full source code for printenv, including the print macro and strlen function, is available at https://gist.github.com/dstein64/a52146a3c6a12c8c0b84cfd4e084bb15.

This entry was tagged , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *