Template tag functions rely on global variables to access the post being processed and retrieve data from it or related to it.
The main variable among these is
$post, which holds the post object itself.
In your example it's not explicit, but what is happening is that your loop assigns data to
$post. If its name wasn't
$post, you would need to name it explicitly (
global $post; $post = $some_other_post;).
However, there are a bunch of other globals and the purpose of
setup_postdata() is to fill them with data. If you look at the source, these are:
global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages;
Note that in most cases you should be calling
wp_reset_postdata() afterwards to return globals to their original state.