I am writing a program to print out all the numbers from zero to 100. The only reason I am doing this is to test out printing out multiple digit numbers.
The problem th
EDIT: it's not an "error" per se, but just misdirection for the casual reader to access a counter and strlen as one byte variables and in other places compare the contents to 32-bit variables...
add BYTE[ecx], NUL
this perhaps adds NUL
terminator to ecx
, but I suppose it should append the terminator.
That could happen at place [ecx+1]
.
Anyway the handling of the variables and pointers is very unconventional in your code...
First: the kernel functions that 'output' stuff, assume that ecx contains the address of a string. There isn't a string allocated anywhere. If the string would just fit into the eight bytes reserved to counter at counter resb 8
, and the counter would contain characters: '1'
,'3'
,'\0'
then the approach would work. And this reveals the second thing: printf deals with strings, which encode single digits 0-9 to values 48-57. Space e.g. in this ASCII system encodes to 32 (decimal) while \NUL is ascii zero.
So, what is needed:
option 1
Initialize your counter
to a string
counter db '0','0','0','0','0','0','0','1'
length dq 1
Ascii zero is not needed to terminate the string, because as I understood, it's given to the print function
Then one can give the real pointer to the string as
lea ecx, counter // get the address of counter string
add ecx, 7 // this is the last character
Also one can increase the counter as a string one digit at a time:
loop:
mov al,[ecx] // assuming ecx still points to last character
inc al
mov [ecx],al
cmp al, '9'
jle string ok
mov al, '0'
mov [ecx],al
dec ecx
jmp loop
ok: // here the counter has been increased correctly
option 2
Increase the counter as a 32-bit integer Convert the integer to string one digit at a time with the following algorithm:
digits = 0;
string_ptr = &my_string[32]; // move barely outside the string
do {
last_digit = a % 10 + '0'; // calculate the last digit and convert to ASCII
a = a / 10;
*--string_ptr = last_digit; // write the last digit
digits++; // count the number of digits
} while (a);
// because we predecrement string_ptr, that value also contains the exact
// start of the first character in the printable string. And digits contains the length.
To produce some good looking result, one has to still add line feeds. That can be handled separately or just appended to the original string -- and ensure they are never written over, so they can be used in all cases.