; general purpose function ; ----------------------- ; int strlen(char *msg) ; calculates string length of msg ; expects string address in eax ; result stored in eax strlen: push ebx ; store ebx on the stack mov ebx, eax ; copy str address into ebx nextchar: cmp byte [eax], 0 ; compare byte eax to zero jz strlenfinished ; jump to finished if zero flag set inc eax ; increment eax jmp nextchar ; jump to nextchar strlenfinished: sub eax, ebx ; get final string length (address-address), store in eax pop ebx ; pop ebx back from the stack ret ; return ; ---------------------- ; ----------------------- ; void printstr(char *str) ; prints string to stdout ; expects string address in eax printstr: ; push e[a-d]x onto the stack push edx push ecx push ebx push eax call strlen ; call string length function mov edx, eax ; strlen leaves result in eax, store in edx pop eax ; pop eax from the stack mov ecx, eax ; store str address in ecx ; write to stdout mov ebx, 1 ; file to write to, stdout mov eax, 4 ; syswrite call int 0x80 ; interrupt ; pop e[b-d]x from the stack (restoring) pop ebx pop ecx pop edx ret ; return ; ----------------------- ; ----------------------- ; void printstrlf(char *str) ; prints string adding a line feed ; expects string in eax printstrlf: call printstr ; print full string push eax ; push eax on to the stack mov eax, 0x0a ; move line feed ascii character into eax push eax ; push line feed onto the stack for later mov eax, esp ; move esp (stack pointer) into eax for printstr (esp -> 0x0a) call printstr ; print line feed pop eax ; remove line feed from the stack pop eax ; restore eax ret ; return ; ----------------------- ; ----------------------- ; void printint(int x) ; prints a integer ; expects an integer in eax printint: ; push e[a,c,d]x, esi onto the stack for restoring later push eax push ecx push edx push esi mov ecx, 0 ; counter of how many bytes we will need to print divideloop: inc ecx ; count a byte to print (number of characters in the number) mov edx, 0 ; clear edx mov esi, 10 ; move 10 into esi idiv esi ; divide eax by esi add edx, 48 ; convert edx to its ascii code - edx holds the remained after a divide instruction push edx ; store edx (ascii representaiton of an integer) on the stack cmp eax, 0 ; check if the integer can be further divided jnz divideloop ; jump if not zero to divideloop printloop: dec ecx ; count downeach byte we put on the stack mov eax, esp ; move the stack pointer into eax for printing call printstr ; print string pop eax ; remove last character printed on the stack to move esp forward cmp ecx, 0 ; check if we have printed all characters we pushed to the stack jnz printloop ; print string if zero flag not set ; restore registers pop esi pop edx pop ecx pop eax ret ; return ; ----------------------- ; ----------------------- ; void printintlf(int x) ; prints an integer and a line feed ; expects an integer in eax printintlf: call printint ; print the integer push eax ; push eax onto the stack to restore later mov eax, 0x0A ; store line feed ascii representation in eax push eax ; push the line feed onto the stack mov eax, esp ; move our stack pointer into eax for printint function call printstr ; print our line feed pop eax ; remove our line feed from the stack pop eax ; restore eax ret ; return ;------------------------ ; ----------------------- ; void exit(void) ; exits the program exit: mov ebx, 0 ; program success mov eax, 1 ; op code 1, sys_exit int 0x80 ; interrupt ; ----------------------