Page 1 of 1

Assembler : Writing A Simple Loop The loop - a fundamental building block

#1 Martyn.Rae  Icon User is offline

  • The programming dinosaur
  • member icon

Reputation: 540
  • View blog
  • Posts: 1,406
  • Joined: 22-August 09

Posted 06 April 2010 - 07:13 AM

Assembler : Writing A Simple Loop

Introduction

The loop is one of the fundamental building blocks of any programming language and for assembler, this is no exception. What we are going to do in this tutorial is look at a simple loop, in the form of a do ... while loop. We shall build on the Hello World tutorial, and instead of printing the text 'Hello World', we will display the ascii characters 0 through to 9.

New Instructions

We shall be using four new instructions for this tutorial. These are

  • mov - move data from a register to memory, memory to a register, or register to register
  • inc - increment a register or memory location
  • cmp - compare a register with memory, memory with register or register with register
  • jb - the jump to location if the condition code flags show as below


The Code

                    ; This is a console application that writes the digits 0 to 9 followed by
                    ; a new line to the console and then exits

                    global      _mainCRTStartup         ; This is the main program entry point
                    extern      _ExitProcess@4          ; Windows API call to exit the process
                    extern      _GetStdHandle@4         ; Windows API call to get the standard output handle
                    extern      _WriteFile@20           ; Windows API call to write to a handle
                    
                    section     .data                   ; Start of the data segment
message             db          '0', 10                 ; The ascii digit zero and a newline message
bytes_written       dd           0                      ; Return 32-bit word from WriteFile
handle              dd           0                      ; The standard output handle
counter             dd           0                      ; Our loop counter initialized to zero

                    section      .code                  ; Start of the code segment
                    
                    ; We need to get hold of the standard output handle so we can write
                    ; our text to it. This is provided by the GetStdHandle windows API call
                    
_mainCRTStartup:    push        -11                     ; We want the standard output handle
                    call        _GetStdHandle@4         ; Call the Windows API GetStdHandle to retrieve it
                    mov         [handle], eax           ; Save the handle for later use
           
                    ; The start of our loop, and the position we return to if we want to
                    ; print out the next digit
                   
start_loop: 
                    push        0                       ; We do not want overlapped I/O
                    push        dword bytes_written     ; The address of the number of bytes written
                    push        2                       ; The length of the text we are writing
                    push        dword message           ; The address of the text we are writing
                    push        dword [handle]          ; The handle returned from GetStdHandle call
                    call        _WriteFile@20           ; Write the text to the standard output handle
                    inc         byte [message]          ; Increment the digit field
                    inc         dword [counter]         ; Increment the counter
                    mov         eax, [counter]          ; Load the counter value into eax
                    cmp         eax, 10                 ; Compare the eax register with a value of 10
                    jb          start_loop              ; Jump back to the start of the loop if eax < 10
                    
                    ; The text has been written, so all we need to do now is exit the
                    ; process and return control back to the console
                    
                    push        0                       ; Stack the exit code
                    call        _ExitProcess@4          ; Exit the process



Note that the message string already contains the first ascii digit of '0', and our counter is also preset to binary zero. The first tweny-two lines are not that much different from the code provided in the Hello World tutorial, so we shall start immediately after the call to GetStdHandle. Here we introduce the first of the new instructions, the mov instruction. There are many forms of this instruction, but in the line

                    mov         [handle], eax           ; Save the handle for later use



we are moving the contents of the eax 32-bit register to the memory location known as handle.

The next line,

start_loop: 
[/code

is a label and is the start of the loop, and the place which we shall return to provided we have not processed the loop more than nine more times.

The next six lines 
[code]
                    push        0                       ; We do not want overlapped I/O
                    push        dword bytes_written     ; The address of the number of bytes written
                    push        2                       ; The length of the text we are writing
                    push        dword message           ; The address of the text we are writing
                    push        dword [handle]          ; The handle returned from GetStdHandle call
                    call        _WriteFile@20           ; Write the text to the standard output handle



are outputting the two characters to the standard output - this is the single digit and the newline character.

The next two lines involve the use of the next new instruction inc, the first of the two lines

                    inc         byte [message]          ; Increment the digit field
                    inc         dword [counter]         ; Increment the counter



adds one to the first byte of our two byte message, taking '0' to ascii '1', and the second line adds one to the memory location known as counter.

The next line,

                    mov         eax, [counter]          ; Load the counter value into eax



is a variant on the previous move instruction which loads the contents of the memory location known as counter into the eax register.

The next line,

                   cmp         eax, 10                 ; Compare the eax register with a value of 10



is another new instruction and compares the contents of the eax with the immediate value of 10 (an immediate value is actually encoded into the instruction stream, rather than being a location in memory. The results of the compare set bits in the condition code register which we can then go on to test.

Finally, we have the last of our new instructions which is the jb instruction tests the condition code flags to determine if the comparison resulted in a less than or below result (the instructions jb and jl are identical).

                    jb          start_loop              ; Jump back to the start of the loop if eax < 10



If the result is true, then the next instruction is at the location known as start_loop, otherwise the next instruction to be executed is the instruction following the jb statement.

Finally, the last two lines of code exit the process.

Results

If you compile and run this code, you should end up with the following output on the console

0
1
2
3
4
5
6
7
8
9



The next tutorial is here.

This post has been edited by Martyn.Rae: 06 April 2010 - 08:57 AM


Is This A Good Question/Topic? 2
  • +

Page 1 of 1