COAL
ASSIGNMENT
#2
[Link]
28057
11-01-2025
Problem no. 1:
1. Create a program that initializes a stack in memory.
2. Push the following 16-bit hexadecimal values onto the stack: 0x1234, 0x5678, and
0x9ABC.
3. Pop the values from the stack and store them in memory locations value1, value2,
and value3.
4. Display the popped values on the screen in the order they were popped.
Solution:
[org 0x100] ; Starting address for COM programs
section .data
value1 dw 0 ; Space to store the first popped value
value2 dw 0 ; Space to store the second popped value
value3 dw 0 ; Space to store the third popped value
section .text
start:
; Put values onto the stack
mov ax, 0x1234 ; Put 0x1234 in AX
push ax ; Save AX on the stack
mov ax, 0x5678 ; Put 0x5678 in AX
push ax ; Save AX on the stack
mov ax, 0x9ABC ; Put 0x9ABC in AX
push ax ; Save AX on the stack
; Take values off the stack
pop ax ; Get the last value (0x9ABC) from the stack
mov [value1], ax ; Save it in value1
pop ax ; Get the second value (0x5678) from the stack
mov [value2], ax ; Save it in value2
pop ax ; Get the first value (0x1234) from the stack
mov [value3], ax ; Save it in value3
; Show the values on the screen
mov ax, [value1] ; Load value1 (0x9ABC) into AX
call print_hex ; Call print_hex to show it
mov ax, [value2] ; Load value2 (0x5678) into AX
call print_hex ; Call print_hex to show it
mov ax, [value3] ; Load value3 (0x1234) into AX
call print_hex ; Call print_hex to show it
; End the program
mov ax, 0x4C00 ; Tell DOS to stop the program
int 0x21
; Subroutine: Print the value in AX as hexadecimal
print_hex:
mov ah, 02h ; Set DOS to print a character
; Print the first digit (leftmost in AX)
mov dl, ah ; Copy the high byte of AX to DL
shr dl, 4 ; Shift right to get the first digit
call print_digit ; Print the digit
; Print the second digit
mov dl, ah ; Copy the high byte of AX to DL again
and dl, 0x0F ; Keep only the lower half
call print_digit ; Print the digit
; Print the third digit
mov dl, al ; Copy the low byte of AX to DL
shr dl, 4 ; Shift right to get the next digit
call print_digit ; Print the digit
; Print the fourth digit (rightmost in AX)
mov dl, al ; Copy the low byte of AX to DL again
and dl, 0x0F ; Keep only the lower half
call print_digit ; Print the digit
; Print a new line
mov dl, 0x0D ; Carriage return
int 0x21 ; Show it
mov dl, 0x0A ; Line feed
int 0x21 ; Show it
ret ; Go back to the main program
; Subroutine: Print one digit
print_digit:
add dl, '0' ; Convert 0-9 to characters '0'-'9'
cmp dl, '9' ; Check if it's 10 or higher
jle print_char ; If not, jump to print_char
add dl, 7 ; Convert to letters A-F
print_char:
int 0x21 ; Show the character in DL
ret ; Go back to the caller
Problem no.2:
Reverse a String Using the Stack
1. Write a program to prompt the user to enter a string (maximum 20 characters).
2. Push each character of the string onto the stack.
3. Pop the characters from the stack and display the reversed string on the screen.
Solution
org 0x100 ; Set the starting memory address for the program (required
for .COM files)
section .data
input db "Hello", 0 ; Define a null-terminated input string "Hello"
section .bss
reversed resb 100 ; Reserve 100 bytes of memory to store the reversed string
section .text
start:
; Initialize registers
mov si, input ; SI register points to the input string
mov di, reversed ; DI register points to the reversed string buffer
; Loop to read characters from the input string and push them onto the stack
read_loop:
mov al, [si] ; Load the current character from the input string into AL
cmp al, 0 ; Check if the character is the null terminator (end of string)
je pop_loop ; If it is, jump to the pop loop
push ax ; Push the character onto the stack
inc si ; Move to the next character in the input string
jmp read_loop ; Repeat the loop
; Pop characters from the stack and store them in the reversed string buffer
pop_loop:
cmp sp, 0xFFFE ; Check if the stack is empty (if the string is fully reversed)
je display_reversed ; If the stack is empty, jump to display the reversed string
pop ax ; Pop a character from the stack into AX register
mov [di], al ; Store the popped character in the reversed buffer
inc di ; Move to the next position in the reversed buffer
jmp pop_loop ; Repeat the loop
; Add the null terminator to the end of the reversed string
display_reversed:
mov byte [di], 0 ; Null-terminate the reversed string
; Print the reversed string using DOS interrupt
mov dx, reversed ; DX points to the reversed string
mov ah, 0x09 ; DOS function 0x09 (display string)
int 0x21 ; Call DOS interrupt
; Exit the program
mov ax, 0x4c00 ; DOS function 0x4C00 (terminate program)
int 0x21 ; Call DOS interrupt
; End of program
Problem no.3:
Postfix Expression Evaluation Using the Stack
1. Write a program to evaluate a simple postfix expression (e.g., 23+5*).
For 23+5*, the result is 25.
Push numbers and operators onto the stack, and perform arithmetic as
required.
2. Use the stack to manage intermediate results.
3. Display the final result of the evaluation.
Solution:
org 0x100 ; Set the starting memory address for the program (required
for .COM files)
section .data
expr db '2', '3', '5', '', '+', 0 ; Define the postfix expression (23+5), terminated by
null
section .bss
stack resb 100 ; Reserve 100 bytes of memory for the stack to hold
operands and intermediate results
section .text
global _start ; Define the program's entry point
_start:
; Set up DS segment register
mov ax, 0x100 ; Load the segment value into AX
mov ds, ax ; Set DS (Data Segment) register to point to the segment
; Initialize registers
xor cx, cx ; Clear CX (counter/index for the expression string)
xor si, si ; Clear SI (index for the stack)
xor bx, bx ; Clear BX (used for storing popped operands)
next_char:
mov al, [expr + ecx] ; Load the current character from the expression
cmp al, 0 ; Check if it's the null terminator (end of string)
je display_result ; If end of expression, jump to display the result
; If the character is a digit
sub al, '0' ; Convert ASCII digit to its numeric value (e.g., '2' -> 2)
cmp al, 9 ; Check if the value is still a valid digit (0-9)
jg operator_found ; If greater than 9, it's an operator (not a digit)
; If it's a number, push it onto the stack
mov [ds:stack + si], al ; Store the number on the stack at position SI
inc si ; Increment SI to point to the next stack position
inc ecx ; Move to the next character in the expression
jmp next_char ; Repeat the process for the next character
operator_found:
; If it's an operator, pop two operands from the stack and perform the operation
dec si ; Decrement SI to get the first operand
mov bx, [ds:stack + si] ; Move the first operand to BX
dec si ; Decrement SI to get the second operand
mov ax, [ds:stack + si] ; Move the second operand to AX
; Check for the '+' operator (addition)
cmp byte [ds:expr + ecx], '+' ; Compare the current character with '+'
je add_operator ; If equal, jump to add_operator
; Check for the '*' operator (multiplication)
cmp byte [ds:expr + ecx], '' ; Compare the current character with ''
je multiply_operator ; If equal, jump to multiply_operator
jmp next_char ; If no operator found, move to the next character
add_operator:
add ax, bx ; Perform addition: AX = AX + BX
mov [ds:stack + si], ax ; Store the result back on the stack
inc si ; Increment SI to the next stack position
inc ecx ; Move to the next character in the expression
jmp next_char ; Repeat the process
multiply_operator:
mul bx ; Perform multiplication: AX = AX * BX
mov [ds:stack + si], ax ; Store the result back on the stack
inc si ; Increment SI to the next stack position
inc ecx ; Move to the next character in the expression
jmp next_char ; Repeat the process
display_result:
; The final result is now on the stack
; Move the result to AX for display
dec si ; Decrement SI to point to the final result
mov ax, [ds:stack + si] ; Move the result to AX
; Convert the result to an ASCII string for display
add ax, 0x3030 ; Convert the result to its ASCII representation
; Display the result using DOS interrupt 0x21, function 0x02 (output character)
mov dl, ah ; Move the high byte of AX to DL
mov ah, 0x02 ; DOS function 0x02 (display character)
int 0x21 ; Call DOS interrupt to display the first character
mov dl, al ; Move the low byte of AX to DL
mov ah, 0x02 ; DOS function 0x02 (display character)
int 0x21 ; Call DOS interrupt to display the second character
; Exit the program properly
mov ax, 0x4c00 ; DOS function 0x4C00 (terminate program)
int 0x21 ; Call DOS interrupt to exit the program
; End of program
Code:
Problem no.4:
Factorial Calculation Using the Stack
1. Write a program to calculate the factorial of a number (n!) using the stack.
2. Prompt the user to input a number (n). 1
3. Use the stack to store intermediate results of the multiplication.
4. Pop and multiply the values to calculate the factorial.
5. Display the result on the screen.
Solution:
org 0x100 ; Set the starting memory address for the program (required
for .COM files)
section .data
result_msg db 'Factorial is: $' ; Message to display the result
prompt_msg db 'Enter a number: $' ; Prompt message for user input
num db 0 ; Variable to store user input (initialized to 0)
section .text
global _start ; Entry point for the program
_start:
; Reset the stack pointer for each run to ensure no corruption
mov ax, 0x9000 ; Set a valid stack pointer location
mov ss, ax ; Set stack segment to the address in ax
mov sp, 0xFFFE ; Set the stack pointer to a valid location
; Display prompt for user input
mov ah, 0x09 ; DOS interrupt to display string
lea dx, [prompt_msg] ; Load the address of prompt_msg into DX
int 0x21 ; Call DOS interrupt to display the prompt
; Read user input (single character)
mov ah, 0x01 ; DOS interrupt to read a character from the keyboard
int 0x21 ; Call DOS interrupt to read the character
sub al, '0' ; Convert the ASCII character to numeric value
mov [num], al ; Store the number in the num variable
; Push the numbers onto the stack (n, n-1, ..., 1)
mov al, [num] ; Load the number (user input) into AL register
mov ah, 0 ; Clear AH register
push_numbers:
cmp ax, 1 ; Check if we have reached 1
jl calculate_factorial ; If less than 1, jump to factorial calculation
push ax ; Push the current value onto the stack
dec ax ; Decrement the number
jmp push_numbers ; Repeat until n = 1
calculate_factorial:
mov ax, 1 ; Initialize the result to 1 (for multiplication)
factorial_loop:
cmp sp, 0xFFFE ; Check if the stack is empty (or stack pointer has gone
out of bounds)
je display_result ; If stack is empty, jump to display the result
pop bx ; Pop the next number from the stack
imul ax, bx ; Multiply the result with the popped number
jmp factorial_loop ; Repeat until the stack is empty
display_result:
; Display the result message
mov ah, 0x09 ; DOS interrupt to display string
lea dx, [result_msg] ; Load the address of result_msg into DX
int 0x21 ; Call DOS interrupt to display the result
; Convert the result to ASCII and display
mov cx, 10 ; Set divisor for converting number to ASCII (base 10)
xor dx, dx ; Clear DX register (used for remainder)
convert_to_ascii:
cmp ax, 0 ; Check if the result is 0
je display_ascii ; If result is 0, jump to display the ASCII characters
div cx ; Divide AX by 10, result in AX, remainder in DX
push dx ; Push the remainder (digit) onto the stack
xor dx, dx ; Clear DX register for next division
jmp convert_to_ascii ; Repeat until result is 0
display_ascii:
cmp sp, 0xFFFE ; Check if the stack is empty
je exit_program ; If stack is empty, exit the program
pop dx ; Pop the next digit from the stack
add dl, '0' ; Convert the digit to ASCII (add '0')
mov ah, 0x02 ; DOS interrupt to display a character
int 0x21 ; Call DOS interrupt to display the digit
jmp display_ascii ; Repeat until the stack is empty
exit_program:
mov ax, 0x4c00 ; DOS interrupt to exit the program
int 0x21 ; Call DOS interrupt to exit
Code: