MASM (Microsoft Macro Assembler) is a powerful tool for writing and assembling low-level assembly language code for x86 and x64 architectures. Below are various practice examples that demonstrate common concepts and instructions in MASM.
Let's start with a simple MASM program that outputs "Hello World" to the console.
; hello.asm
.model small
.stack 100h
.data
helloMessage db 'Hello, World!', 0
.code
main:
mov ax, @data ; Initialize data segment
mov ds, ax
; Print "Hello, World!"
mov ah, 09h ; DOS function to print string
lea dx, helloMessage ; Load the address of the string
int 21h ; Call DOS interrupt
; Exit the program
mov ah, 4Ch ; DOS function to terminate program
int 21h ; Call DOS interrupt
end main
.model small: Defines a small memory model where both data and code fit within a single segment..stack 100h: Reserves 256 bytes of stack memory..data: Declares the data segment, where we define the helloMessage string..code: Marks the start of the code segment.mov ax, @data and mov ds, ax: Initializes the data segment.mov ah, 09h: Prepares to call DOS interrupt 21h to display a string.lea dx, helloMessage: Loads the address of the string into the DX register.int 21h: Calls DOS interrupt 21h to print the string.mov ah, 4Ch and int 21h: Terminates the program.To assemble and run:
hello.asm.ml hello.asmlink hello.objThis example performs basic arithmetic operations like addition, subtraction, multiplication, and division.
; arithmetic.asm
.model small
.stack 100h
.data
num1 dw 10 ; Define first number
num2 dw 5 ; Define second number
result dw 0 ; Variable to store result
.code
main:
mov ax, @data ; Initialize data segment
mov ds, ax
; Load numbers
mov ax, num1 ; AX = num1 (10)
mov bx, num2 ; BX = num2 (5)
; Addition
add ax, bx ; AX = AX + BX (10 + 5)
mov result, ax ; Store result (15)
; Subtraction
mov ax, num1 ; Load num1 again
sub ax, bx ; AX = AX - BX (10 - 5)
mov result, ax ; Store result (5)
; Multiplication
mov ax, num1 ; Load num1 again
mov bx, num2 ; Load num2 again
mul bx ; AX = AX * BX (10 * 5)
mov result, ax ; Store result (50)
; Division
mov ax, num1 ; Load num1 again
mov bx, num2 ; Load num2 again
div bx ; AX = AX / BX (10 / 5), result in AX, remainder in DX
mov result, ax ; Store result (2)
; Exit the program
mov ah, 4Ch ; DOS function to terminate program
int 21h ; Call DOS interrupt
end main
mov ax, num1 and mov bx, num2: Loads num1 and num2 into the registers AX and BX.add ax, bx: Adds the contents of BX to AX (10 + 5).sub ax, bx: Subtracts BX from AX (10 - 5).mul bx: Multiplies AX by BX (10 * 5), storing the result in AX.div bx: Divides AX by BX (10 / 5). The quotient is in AX, and the remainder is in DX.result variable.This example demonstrates how to use loops in MASM. The loop will count from 1 to 10 and print the number each time.
; loop.asm
.model small
.stack 100h
.data
msg db 'The number is: $'
counter db 1 ; Counter starts at 1
.code
main:
mov ax, @data ; Initialize data segment
mov ds, ax
start_loop:
; Print message
mov ah, 09h ; DOS function to print string
lea dx, msg ; Load the address of the message
int 21h ; Call DOS interrupt
; Print counter
mov al, counter ; Load the current counter value
call PrintNum ; Call the PrintNum procedure
; Increment counter
inc counter ; Increment counter by 1
cmp counter, 11 ; Check if counter is 11
jl start_loop ; Jump to start_loop if counter < 11
; Exit program
mov ah, 4Ch ; DOS function to terminate program
int 21h ; Call DOS interrupt
; PrintNum procedure
PrintNum:
; Print the number in AL (assuming AL holds a number < 10)
add al, '0' ; Convert number to ASCII
mov dl, al ; Move number to DL register
mov ah, 02h ; DOS function to print a character
int 21h ; Call DOS interrupt
ret ; Return from procedure
end main
counter db 1: Initializes a counter variable starting at 1.lea dx, msg: Loads the address of the string into the DX register.int 21h: Uses DOS interrupt 21h to print the string.cmp instruction (cmp counter, 11), checking if counter is less than 11. If true, it loops again.PrintNum procedure is used to print a single number by converting it into ASCII.This example simulates an "if-else" block using conditional jumps.
; if_else.asm
.model small
.stack 100h
.data
msg_true db 'The condition is true.$'
msg_false db 'The condition is false.$'
condition db 1 ; Set the condition to 1 (True)
.code
main:
mov ax, @data ; Initialize data segment
mov ds, ax
mov al, condition ; Load the condition value into AL
cmp al, 1 ; Compare condition with 1
je true_condition ; Jump if condition is true (AL == 1)
; Else part
mov ah, 09h ; DOS function to print string
lea dx, msg_false ; Load the "false" message
int 21h
jmp end_program ; Jump to end
true_condition:
; If part
mov ah, 09h ; DOS function to print string
lea dx, msg_true ; Load the "true" message
int 21h
end_program:
; Exit the program
mov ah, 4Ch ; DOS function to terminate program
int 21h ; Call DOS interrupt
end main
condition db 1: This is a variable that controls the conditional flow. You can change it to 0 for the "false" branch.cmp al, 1: Compares the value of AL (which contains the condition) with 1.je true_condition: If AL == 1, jump to the true_condition label to print the true message.AL != 1), the program prints the false message.In this example, we'll define a function that adds two numbers and returns the result.
; function_call.asm
.model small
.stack 100h
.data
num1 dw 5 ; First number
num2 dw 3 ; Second number
result dw 0 ; Store result
.code
main:
mov ax, @data ; Initialize data segment
mov ds, ax
; Call AddNumbers function
mov ax, num1 ; Load num1 into AX
mov bx, num2 ;
Open this section to load past papers