Chapter 6: The strint Function

In this chapter, I will only be introducing one program that uses the three previous functions I described in earlier parts of this book but also includes one more important one!

What this program does is really quite simple, it takes a string of binary integers called “test_int” and converts it into a real integer using a new function called “strint”.

Below is the source of this program. Take a minute to look it over. Afterwards, I will explain more about the “strint” function and how it interacts with the other three functions. “putstring”,“intstr”,and “putint”.

The Program

 1 org 100h
 2 
 3 main:
 4 
 5 mov ax,main_string
 6 call putstring
 7 
 8 mov word [radix],2 ; choose radix for integer input/output
 9 mov word [int_width],1
10 
11 mov ax,test_int
12 call strint
13 
14 mov bx,ax
15 
16 mov ax,str_bin
17 call putstring
18 mov ax,bx
19 mov word [radix],2
20 call putint
21 
22 mov ax,str_hex
23 call putstring
24 mov ax,bx
25 mov word [radix],16
26 call putint
27 
28 mov ax,str_dec
29 call putstring
30 mov ax,bx
31 mov word [radix],10
32 call putint
33 
34 mov ax,4C00h
35 int 21h
36 
37 main_string db "This is the year I was born",0Dh,0Ah,0
38 
39 ;test string of integer for input
40 test_int db '11111000011',0
41 
42 str_bin db 'binary: ',0
43 str_hex db 'hexadecimal: ',0
44 str_dec db 'decimal: ',0
45 
46 include 'chastelib16.asm'

For a quick review, the 3 previous function do the following.

  • putstring: prints a zero terminated string pointed to by ax register
  • intstr: converts the integer in ax register into a zero terminated string and then points ax to that string for compatibility with putstring
  • putint: calls intstr and then putstring to display whatever number ax equals

And now I introduce to you the final function of my 4 function library that I call “chastelib”.

This function is called “strint” and its importance cannot be overstated. It does the opposite of the “intstr” function. Instead of converting an integer to a string, it does the opposite and takes the string pointed to by ax and converts it into a number returned in the ax register. Much like “intstr”, it uses the global [radix] variable to know which base is being used.

But the very nature of turning a string into an integer is more complicated by necessity. Any valid 16 bit number can be turned into a string from bases 2 to 36 by the “intstr” function. However, strings can contain characters that are invalid to be converted as numbers. There is also the issue that both capital and lowercase letters might be used in radixes higher than ten. In the program above, I used a binary integer string for an example, but in real applications, such as a famous program I wrote called “chastehex”, it is necessary to write a function that can gracefully handle not only the decimal digits ‘0’ to ‘9’ but also handle letters ‘A’ to ‘Z’ or ‘a’ to ‘z’.

Below is the full source code of the strint function as written for 16 bit DOS Assembly programs. I spent more time writing this function than the three previous functions combined, but it was necessary for the programs I intended to write! Comments are included although more explanation may be required for some to understand it.

The Function

 1 ;this function converts a string pointed to by ax into an integer returned in ax instead
 2 ;it is a little complicated because it has to account for whether the character in
 3 ;a string is a decimal digit 0 to 9, or an alphabet character for bases higher than ten
 4 ;it also checks for both uppercase and lowercase letters for bases 11 to 36
 5 ;finally, it checks if that letter makes sense for the base.
 6 ;For example, G to Z cannot be used in hexadecimal, only A to F can
 7 ;The purpose of writing this function was to be able to accept user input as integers
 8 
 9 strint:
10 
11 mov bx,ax ;copy string address from ax to bx because ax will be replaced soon!
12 mov ax,0
13 
14 read_strint:
15 mov cx,0 ; zero cx so only lower 8 bits are used
16 mov cl,[bx] ;copy byte/character at address bx to cl register (lowest part of cx)
17 inc bx ;increment bx to be ready for next character
18 cmp cl,0 ; compare this byte with 0
19 jz strint_end ; if comparison was zero, this is the end of string
20 
21 ;if char is below '0' or above '9', it is outside the range of these and is not a digit
22 cmp cl,'0'
23 jb not_digit
24 cmp cl,'9'
25 ja not_digit
26 
27 ;but if it is a digit, then correct and process the character
28 is_digit:
29 sub cl,'0'
30 jmp process_char
31 
32 not_digit:
33 ;it isn't a decimal digit, but it could be perhaps an alphabet character
34 ;which could be a digit in a higher base like hexadecimal
35 ;we will check for that possibility next
36 
37 ;if char is below 'A' or above 'Z', it is outside the range of these and is not capital letter
38 cmp cl,'A'
39 jb not_upper
40 cmp cl,'Z'
41 ja not_upper
42 
43 is_upper:
44 sub cl,'A'
45 add cl,10
46 jmp process_char
47 
48 not_upper:
49 
50 ;if char is below 'a' or above 'z', it is outside the range of these and is not lowercase letter
51 cmp cl,'a'
52 jb not_lower
53 cmp cl,'z'
54 ja not_lower
55 
56 is_lower:
57 sub cl,'a'
58 add cl,10
59 jmp process_char
60 
61 not_lower:
62 
63 ;if we have reached this point, result invalid and end function
64 jmp strint_end
65 
66 process_char:
67 
68 cmp cx,[radix] ;compare char with radix
69 jae strint_end ;if this value is above or equal to radix, it is too high despite being a valid digit/alpha
70 
71 mov dx,0 ;zero dx because it is used in mul sometimes
72 mul word [radix]    ;mul ax with radix
73 add ax,cx
74 
75 jmp read_strint ;jump back and continue the loop if nothing has exited it
76 
77 strint_end:
78 
79 ret

If you run the program at the top of this chapter (remember the source is available on github but also can be pieced together from this book alone), it will produce this output.

The Output

1 This is the year I was born
2 binary: 11111000011
3 hexadecimal: 7C3
4 decimal: 1987

These three forms of displaying the same number are quite obviously the most useful radixes that programmers must learn.

Binary is what computers understand. Without knowing that everything is bits of only 0 or 1, very little about computers makes sense without a complete understanding of the Binary Numeral System.

Hexadecimal is the short form of Binary because every four bits equals one digit in Hexadecimal. For this reason, hex editors for editing binary files are much more common than binary editors. It just takes less typing and disk space.

Decimal actually has no value other than what humans have placed on it. Base ten is not special, and computers don’t understand it as well as Binary, but humans expect numbers to be in this form, and by extension, all the video games also display numbers in this form.

If I told people that I was born in 11111000011, they will think I am really old and should be dead by now. If I tell them I was born in 1987, they will know that I am 38 years old at the time I am writing this book. However, both numbers mean the exact same thing.

The reason I mention this is that I want you to research different bases/radixes of number systems because it will make you a better programmer. In fact there is a really good book written by another author that I will recommend.

Binary, Octal and Hexadecimal for Programming & Computer Science by Sunil Tanna https://www.amazon.com/Binary-Hexadecimal-Programming-Computer-Science-ebook/dp/B07F6Y7JX1