<p>This is kinda oddball, but I was poking around with the GNU assembler today (I want to be able to at least read the syntax), and was trying to get this little contrived example of mine to work. Namely I just want to go from 0 to 100, printing out numbers all the while. So a few minutes later I come up with this:</p>

<pre><code># count.s: print the numbers from 0 to 100. 
    .text
string: .asciz "%d\n"
    .globl _main

_main:
    movl    $0, %eax # The starting point/current value.
    movl    $100,   %ebx # The ending point.

_loop:
    # Display the current value.
    pushl   %eax
    pushl   $string
    call     _printf
    addl     $8, %esp

    # Check against the ending value.
    cmpl    %eax, %ebx
    je    _end

    # Increment the current value.
    incl    %eax
    jmp _loop   

_end:
</code></pre>

<p>All I get from this is 3 printed over and over again. Like I said, just a little contrived example, so don't worry too much about it, it's not a life or death problem.</p>

<p>(The formatting's a little messed up, but nothing major).</p>

[{'answer_id': 19411, 'author': 'Nathan Fellman', 'author_id': 1084, 'author_profile': 'https://Stackoverflow.com/users/1084', 'pm_score': 3, 'selected': False, 'text': "<p>I'm not too familiar with _printf, but could it be that it modifies eax?  Printf should return the number of chars printed, which in this case is two: '0' and '\\n'.  I think it returns this in eax, and when you increment it, you get 3, which is what you proceed to print.\nYou might be better off using a different register for the counter.</p>\n"}, {'answer_id': 19453, 'author': 'seanyboy', 'author_id': 1726, 'author_profile': 'https://Stackoverflow.com/users/1726', 'pm_score': 5, 'selected': True, 'text': '<p>You can\'t trust what any called procedure does to any of the registers. \nEither push the registers onto the stack and pop them back off after calling printf or have the increment and end point values held in memory and read/written into registers as you need them. </p>\n\n<p>I hope the following works. I\'m assuming that pushl has an equivalant popl and you can push an extra couple of numbers onto the stack. </p>\n\n<pre><code># count.s: print the numbers from 0 to 100. \n    .text\nstring: .asciz "%d\\n"\n    .globl _main\n\n_main:\n    movl    $0, %eax # The starting point/current value.\n    movl    $100,       %ebx # The ending point.\n\n_loop:\n    # Remember your registers.\n    pushl   %eax\n    pushl   %ebx\n\n    # Display the current value.\n    pushl   %eax\n    pushl   $string\n    call     _printf\n    addl     $8, %esp\n\n    # reinstate registers.\n    popl   %ebx\n    popl   %eax\n\n    # Check against the ending value.\n    cmpl    %eax, %ebx\n    je    _end\n\n    # Increment the current value.\n    incl    %eax\n    jmp _loop   \n\n_end:\n</code></pre>\n'}, {'answer_id': 19459, 'author': 'Wedge', 'author_id': 332, 'author_profile': 'https://Stackoverflow.com/users/332', 'pm_score': 1, 'selected': False, 'text': "<p>Nathan is on the right track. You can't assume that register values will be unmodified after calling a subroutine. In fact, it's best to assume they will be modified, else the subroutine wouldn't be able to do it's work (at least for low register count architectures like x86). If you want to preserve a value you should store it in memory (e.g. push it onto the stack and keep track of it's location).</p>\n\n<p>You'll need to do the same for any other variable you have. Using registers to store local variables is pretty much reserved to architectures with enough registers to support it (e.g. EPIC, amd64, etc.)</p>\n"}, {'answer_id': 19542, 'author': 'Nathan Fellman', 'author_id': 1084, 'author_profile': 'https://Stackoverflow.com/users/1084', 'pm_score': 2, 'selected': False, 'text': "<p>Well written functions will usually push all the registers onto the stack and then pop them when they're done so that they remain unchanged during the function.  The exception would be eax that contains the return value.  Library functions like printf are most likely written this way, so I wouldn't do as Wedge suggests:</p>\n\n<blockquote>\n  <p>You'll need to do the same for any other variable you have. Using registers to store local variables is pretty much reserved to architectures with enough registers to support it (e.g. EPIC, amd64, etc.)</p>\n</blockquote>\n\n<p>In fact, from what I know, compilers usually compile functions that way to deal exactly with this issue.</p>\n\n<p>@seanyboy, your solution is overkill.  All that's needed is to replace eax with some other register like ecx.</p>\n"}, {'answer_id': 21148, 'author': 'Brad Gilbert', 'author_id': 1337, 'author_profile': 'https://Stackoverflow.com/users/1337', 'pm_score': -1, 'selected': False, 'text': '<p>You could rewrite it so that you use registers that aren\'t suppose to change, for example <code>%ebp</code>. Just make sure you push them onto the stack at the beginning, and pop them off at the end of your routine.</p>\n\n<pre><code># count.s: print the numbers from 0 to 100. \n    .text\nstring: .asciz "%d\\n"\n    .globl _main\n\n_main:\n    push    %ecx\n    push    %ebp\n    movl    $0, %ecx # The starting point/current value.\n    movl    $100,       %ebp # The ending point.\n\n_loop:\n    # Display the current value.\n    pushl   %ecx\n    pushl   $string\n    call     _printf\n    addl     $8, %esp\n\n    # Check against the ending value.\n    cmpl    %ecx, %ebp\n    je    _end\n\n    # Increment the current value.\n    incl    %ecx\n    jmp _loop   \n\n_end:\n    pop     %ebp\n    pop     %ecx\n</code></pre>\n'}, {'answer_id': 43095, 'author': 'alex strange', 'author_id': 4478, 'author_profile': 'https://Stackoverflow.com/users/4478', 'pm_score': 3, 'selected': False, 'text': '<p>You can safely use registers that are "callee-saved" without having to save them yourself. On x86 these are edi, esi, and ebx; other architectures have more.</p>\n\n<p>These are documented in the ABI references: <a href="http://math-atlas.sourceforge.net/devel/assembly/" rel="noreferrer">http://math-atlas.sourceforge.net/devel/assembly/</a></p>\n'}]
['https://Stackoverflow.com/questions/19409', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/61/']