I have created two functions in x86 Assembly Language that allow me to output any zero terminated string or output any integer in any base from 2 to 36. I will show the full source so people can play with it. This uses system calls on Linux so it won’t work on Windows.
first, the header file “chaste-lib.asm”
; This file is where I keep my function definitions.
; These are usually my string and integer output routines.
putstring: ; function to print zero terminated string pointed to by register eax
mov edx,eax ; copy eax to edx as well. Now both registers have the address of the main_string
strlen_start: ; this loop finds the lenge of the string as part of the putstring function
cmp [edx],byte 0 ; compare byte at address edx with 0
jz strlen_end ; if comparison was zero, jump to loop end because we have found the length
inc edx
jmp strlen_start
strlen_end:
sub edx,eax ; edx will now have correct number of bytes when we use it for the system write call
mov ecx,eax ; copy eax to ecx which must contain address of string to write
mov eax, 4 ; invoke SYS_WRITE (kernel opcode 4)
;mov ebx, 1 ; ebx=1 means write to the STDOUT file
int 80h ; system call to write the message
ret ; this is the end of the putstring function return to calling location
radix dd 16 ;radix or base for integer output. 2=binary, 16=hexadecimal, 10=decimal
putint: ; function to output decimal form of whatever integer is in eax
push eax ;save eax on the stack to restore later
mov ebp,int_string+31 ;address of start digits
digits_start:
mov edx,0;
mov esi,[radix] ;radix is from memory location just before this function
div esi
cmp edx,10
jb decimal_digit
jge hexadecimal_digit
decimal_digit: ;we go here if it is only a digit 0 to 9
add edx,'0'
jmp save_digit
hexadecimal_digit:
sub edx,10
add edx,'A'
save_digit:
mov [ebp],dl
cmp eax,0
jz digits_end
dec ebp
jmp digits_start
digits_end:
mov eax,ebp ; now that the digits have been written to the string, display it!
call putstring
pop eax ;load eax from the stack so it will be as it was before this function was called
ret
next, the main source that includes the header: “main.asm”
format ELF executable
entry main
include 'chaste-lib.asm'
main: ; the main function of our assembly function, just as if I were writing C.
; I can load any string address into eax and print it!
mov ebx, 1 ;ebx must be 1 to write to standard output
mov eax,msg
call putstring
mov eax,main_string ; move the address of main_string into eax register
call putstring
mov [radix],2 ; can choose radix for integer output!
mov eax,0
loop1:
call putint
inc eax
cmp eax,100h;
jnz loop1
mov eax, 1 ; invoke SYS_EXIT (kernel opcode 1)
mov ebx, 0 ; return 0 status on exit - 'No Errors'
int 80h
; this is where I keep my string variables
msg db 'Hello World!', 0Ah,0 ; assign msg variable with your message string
main_string db "This is Chastity's Assembly Language counting program!",0Ah,0
int_string db 32 dup '?',0Ah,0
; This Assembly source file has been formatted for the FASM assembler.
; The following 3 commands assemble, give executable permissions, and run the program
;
; fasm main.asm
; chmod +x main
; ./main
If you have the fasm compiler, you can assemble this source on any Linux distribution running on an intel CPU. Assembly is platform specific but it runs really fast and the process of programming with it is enjoyable for me.
Please leave me any comments or questions you have! I will update posts if necessary based on user feedback!