Search code examples
assemblyx86masmirvine32

How does the following Assembly language code run?


I know nothing about assembly, but I am given an assignment of this.

Please tell me how does the following code run? I mean the steps or procedures.

TITLE MASM Template (main.asm)

; Description: 
;
; Revision date:f

INCLUDE Irvine32.inc
.data
counter dword 1;
instruct1 BYTE"How many line are required?: ",0 ;give instruction to user to give the input
answer BYTE"Answer:",0

newline BYTE 0Dh, 0Ah

sum BYTE 0

.code
main PROC
mov edx,OFFSET instruct1 ;move instruct1 to edx
call WriteString
call readint;
mov ecx,eax; move ecx to eax
L1:

push ecx;
mov ecx,counter
L2:
mov al,'*';add '*' into al
call writechar;


loop l2;
pop ecx;
inc counter;
call crlf;
loop l1;



exit
main ENDP

end main

Solution

  • This code prints a prompt and inputs a number. It then prints that number of lines of stars. On the first line is 1 star, the second line 2 stars, and so on. I have annotated the code to make it more clear.

    The code does this with two nested loops. The ecx register is used for both loops: as a counter for the stars on each line, and for the line count. That is why ecx is pushed and popped, so it can have another count in the inner loop.

    TITLE MASM Template (main.asm)      ;used for listings etc.
    
    ; Description: 
    ;
    ; Revision date:f
    
    INCLUDE Irvine32.inc                ;include another code file
    
    .data                               ;data segment
    
    counter dword 1                     ;characters per line
    instruct1 BYTE"How many line are required?: ",0
    answer BYTE"Answer:",0              ;irrelevant to this code
    newline BYTE 0Dh, 0Ah               ;used by crlf
    sum BYTE 0                          ;irrelevant to this code
    
    .code                               ;code segment
    
        main PROC                       ;declare code block
    
        mov edx,OFFSET instruct1        ;message pointer
        call WriteString                ;display message
        call readint                    ;input an integer
        mov ecx,eax                     ;move input to line loop register
    L1:
        push ecx                        ;save line count register
        mov ecx,counter                 ;load character counter
    L2:
        mov al,'*'                      ;the char we wish to print
        call writechar                  ;output one char
        loop L2                         ;next character (count in cx)
        pop ecx                         ;restore the line counter
        inc counter                     ;increment characters per line
        call crlf                       ;print the newline defined above
        loop L1                         ;next line (count in cx)
    
        exit                            ;return to OS
        main ENDP                       ;end code block
        end main                        ;end of code file
    

    If the input is 3, the output will be:

    *
    **
    ***
    

    As an aside, I would criticise the author of the code for the following line, for two reasons.

    mov ecx,eax     ; move ecx to eax
    

    Reason 1. The comment is back to front; move the returned value eax to ecx for the line counter

    Reason 2: Never use a comment to explain what an instruction does, you can RTM for that. Use comments for added value, to make it clear what the purpose is.