Subroutines in Assembly Language

In assembly language, procedures and subroutines are essentially the same concept—blocks of code that perform a specific task and are called from other parts of the program.

The following assembly language code defines a procedure called print_string:

print_string: mov edi, [rsi] call _puts ret

This procedure prints the string at the address specified by the register RSI.

The following assembly language code calls the print_string procedure:

lea rsi, my_string call print_string

This code will print the string "Hello, world!" to the console.

Here's a step-by-step explanation with examples, using x86 assembly as a reference:

Procedure Definition

Define a label to mark the beginning of the procedure or subroutine.

section .text global _start my_procedure: ; Procedure code here ret ; Return instruction

Procedure Parameters

If needed, pass parameters to the procedure using registers or the stack.

section .text global _start my_procedure: mov eax, [ebp+8] ; Access the first parameter on the stack ; Procedure code here ret

Procedure Call

Call the procedure using the call instruction.

section .text global _start _start: ; Prepare parameters mov eax, 42 ; Call the procedure call my_procedure

Return Value

Procedures can return values in registers or memory locations.

section .text global _start my_procedure: mov eax, 10 ; Set return value ret
Full Source

Here's an example of a procedure that adds two numbers:

section .text global _start _start: ; Prepare parameters mov eax, 5 mov ebx, 7 ; Call the procedure call add_procedure ; Result is now in eax ; Exit program mov eax, 1 ; System call number for exit xor ebx, ebx ; Exit code 0 int 0x80 ; Invoke system call add_procedure: ; Procedure code add eax, ebx ; Add parameters ret

In this example, _start prepares two parameters (eax and ebx), calls the add_procedure subroutine, and the result is in eax after the call. The add_procedure subroutine adds the parameters and returns using the ret instruction. Adjust the code inside the procedure according to your specific requirements.

Difference between procedures and subroutines

The terms "procedures" and "subroutines" are often used interchangeably in assembly language programming. However, there is a subtle difference between the two. A procedure is a block of code that performs a complete task. A subroutine is a block of code that performs a subtask of a larger task.

For example, the print_string procedure performs a complete task: it prints a string to the console. The reverse_string function from my previous example is a subroutine: it performs the subtask of reversing the order of the characters in a string.

In general, procedures are used to implement high-level tasks, such as printing to the console or reading input from the user. Subroutines are used to implement low-level tasks, such as reversing the order of the characters in a string or calculating the factorial of a number.

Conclusion

Procedures and subroutines are blocks of code identified by labels, designed to perform specific tasks. They can take parameters, be called using the call instruction, and return values through the ret instruction, facilitating modular and reusable code structures.