assemblyx86reusability

Print the greatest number in assembly programming


Trying to print the greatest number (a & b) by using the below assembly code. But it is printing the "first" (Welcome) message only. I just want to print the "second" (i.e greatest) message as well.

[IsGreater.asm]

; Compares the two operand (A & B)
; Prints "YES" if "A > B"
; Prints "NO" if "A < B"
; Prints "EQUAL" if "A == B"


section .data;
    Message: db "Welcome to comparision program.", 10;
    MessageLength: equ $-Message;

    AMessage: db "Output: A is greater than B.", 10;
    AMessageLength: equ $-AMessage;

    BMessage: db "Output: B is greater than A.", 10;
    BMessageLength: equ $-BMessage;


section .bss;
    ; Dynamic variables
    a: resb 4;
    b: resb 5;


section .text;
    global _start;

; -----------------
write:
    mov eax, 4; sys_write
    mov ebx, 1; file descriptor (output)

    mov ecx, Message;
    mov edx, MessageLength;

    int 80h;  sys_call (execute)


exit:
    mov eax, 1; sys_exit
    mov ebx, 0; set "no error"

    int 80h; sys_call


printA:
    mov eax, 4; sys_write
    mov ebx, 1; file descriptor (output)

    mov ecx, AMessage;
    mov edx, AMessageLength;

    int 80h;  sys_call (execute)

printB:
    mov eax, 4; sys_write
    mov ebx, 1; file descriptor (output)

    mov ecx, BMessage;
    mov edx, BMessageLength;

    int 80h;  sys_call (execute)


_start:
    jmp write;

    ; mov word [a], 4;
    mov eax, [a];


    ; mov word [b], 5;
    mov ebx, [b];


    ; Compare "a > b"
    cmp eax, ebx;
    jg printA; Jump IF Greater  (OR) when "Zero Flag" ZF is "0".
    jmp printB; Else print B

    jmp exit;

Current Output:

$ ./IsGreater

Welcome to comparision program.

Expected Output:

$ ./IsGreater

Welcome to comparision program.

Output: B is greater than A.

Compile Command: $ nasm IsGreater.asm -o IsGreater.o -f elf -F STABS -g

Linking Command: $ ld IsGreater.o -o IsGreater -m elf_i386

Run Command : $ ./IsGreater

Also please suggest the way to reuse the same "write" code block (i.e "Message" variable) to print the another string rather than declaring for new variable. ("AMessage" & "BMessage").

Thanks in advance.


Solution

  • Your program starts by jumping to write.
    Immediately following write is exit.

    The program will just fall through.
    It will not return to start, because you did a jmp.
    It will just continue executing instructions.

    Instead, you should use the call instruction to call into write, with a ret inside write to return to the caller.

    About the second question, simply populate ecx and edx before calling write, with the correct variables. The write function only needs to care about eax, ebx and issue the system call.

    write:
        mov eax, 4
        mov ebx, 1
        int 80h
        ret
    
    _start:
        mov ecx, foo
        mov edx, fooLength
        call write
        
        mov ecx, bar
        mov edx, barLength
        call write