Skip to content
UoL CS Notes

Calling External Subroutines for I/O

COMP124 Lectures

This calls the subroutines from the C libraries to provide I/O functions.

External Subroutines

In order to call external subroutines from assembly the parameters need to be pushed to the stack.

printf

This function prints to the standards output.

  • It expects its parameters to be on the stack.
  • It expect the string parameter to be passed by reference.
  • It will not remove the parameter from the stack, so you must do it afterwards.

Assembly Example

#include <stdio.h>
#include <stdlib.h>
int main (void) {
	char msg[] = "Hello World\n"; // declare string in c
	_asm {
		lea eax, msg	; put address of string in eax
		push eax	; stack the parameter
		call printf	; use library function
		pop eax	; take parameter off stack
	}
	return 0;
}

Looping Problem

Suppose we want to print our message 10 times. Then we might try making a standard loop.

The issue is that we don’t know what is going on inside the external routine. As a result we have to assume that any registers we are using will be overwritten.

This means we must save register values before the call, and restore them after. This should be done via the stack.

	mov ecx, 10	; set up loop counter
loop1:
	push ecx	; save ecx on stack
	lea eax, msg
	push eax	; stack the parameter
	call printf	; use the function
	pop eax	; remove param
	pop ecx ; restore ecx
	loop loop1	; loop based on ecx

Format Specifiers

The string parameter to printf() can contain format specifiers.

Each format specifier refers to another parameter, and tell printf() how it should be printed.

int age = 21; char name[] = "Bob";
printf("My name is %s and my age is %d\n", name, age);

This will print:

My name is Bob and my age is 21.

Some formats:

  • %d - Print as decimal integer.
  • %s - Print as string.
  • %c - Print as character.
  • %f - Print as floating point.

Example

We will do the equivalent of:

printf("Number is %d\n", n);

We have to pass both paramters:

  • The string’s address.
  • The value of n.

These must be paced on the stack in reverse order.

#include <stdio.h>
#include <stdlib.h>
int main (void) {
	char msg[] = "Number is %d\n", n;
	int n = 157;
	
	_asm {
		push n 	; push the int first
		lea eax, msg
		push eax	; now stack the string
		call printf
		add esp, 8 ; clean 8 bytes from stack
	}
	return 0;
}

The final instruction cleans the data from the stack without loading each value into eax.

scanf

Reading values from the keyboard can be achieved by using scanf():

scanf("%d", &num); // format specifiers for inputs are mandatory

We have to tell scanf() where to put the item being read. That means passing the address of the variable.

Example

char fmt[] = "%d";
int num;
_asm {
	lea eax, num	; we need to push the address of num
	push eax
	lea eax, fmt	; now the format string
	push eax
	call scanf	; on return the value will be stored
	add esp, 8	; clean stack
	}