char * trouble??
char * trouble??
Hi everyone,
Well I started to try to write some low level string routines but I have run into a stumbling block. I have an assembly routine that is called through my C kerel that takes a char value as well as the address onscreen for the char to be placed. In fact right now the only thing in my C kernel are the print_char function calls. This works fine when called explicitly like:
print_char('H',0xb8000);
print_char('i',0xb8002);
prints Hi in the top left of the screen....
however, if I try this:
char *str = "Hi";
char *x = str;
while ( *x != '\0')
{
print_char(*x, 0xb8000);
x = x + 1;
}
I get a blank printed and nothing else. I have tried just about every other way of doing this: using a char array, using a subroutine etc. and nothing changes it. It just doesn't make sense to me how I can declare 20 char types and print them individually (or even through a char pointer) but as soon as I try to declare a string and pass its dereferenced value to print_char nothing happens. Any Ideas???
Thanks,
Nicole
Well I started to try to write some low level string routines but I have run into a stumbling block. I have an assembly routine that is called through my C kerel that takes a char value as well as the address onscreen for the char to be placed. In fact right now the only thing in my C kernel are the print_char function calls. This works fine when called explicitly like:
print_char('H',0xb8000);
print_char('i',0xb8002);
prints Hi in the top left of the screen....
however, if I try this:
char *str = "Hi";
char *x = str;
while ( *x != '\0')
{
print_char(*x, 0xb8000);
x = x + 1;
}
I get a blank printed and nothing else. I have tried just about every other way of doing this: using a char array, using a subroutine etc. and nothing changes it. It just doesn't make sense to me how I can declare 20 char types and print them individually (or even through a char pointer) but as soon as I try to declare a string and pass its dereferenced value to print_char nothing happens. Any Ideas???
Thanks,
Nicole
RE:char * trouble??
Hello.
Well, it looks fine to me, except you're not incrementing your destination address. That shouldn't be the reason for a blank screen tho. Try this:
char * str = "Hi";
int idx = 0;
while(str[idx] != 0) {
print_char(str[idx], 0xb8000 + idx);
idx = idx + 1;
}
Its pretty similar to the code you wrote, but I always find that when something should blatantly work and doesn't, it can sometimes help to just go about it from a slightly different angle
Well, it looks fine to me, except you're not incrementing your destination address. That shouldn't be the reason for a blank screen tho. Try this:
char * str = "Hi";
int idx = 0;
while(str[idx] != 0) {
print_char(str[idx], 0xb8000 + idx);
idx = idx + 1;
}
Its pretty similar to the code you wrote, but I always find that when something should blatantly work and doesn't, it can sometimes help to just go about it from a slightly different angle
RE:char * trouble??
Bother.
replace
print_char(str[idx], 0xb8000 + idx);
with
print_char(str[idx], 0xb8000 + idx * 2);
Sorry about that .
replace
print_char(str[idx], 0xb8000 + idx);
with
print_char(str[idx], 0xb8000 + idx * 2);
Sorry about that .
RE:char * representation
Oh yes,
I'm sorry I left out the:
address = address + 2;
line in the code I posted, I do have it in my source files though. I have also tried the suggested method of manipulating the char* like an array:
char *string = "Hello";
int i = 0;
int address = 0xB8000;
while ( string[i] != '\0' )
{
print_char( string[i], address)
i++;
address = address + 2;
}
But that still doesn't work, It just prints one blank at the location of the original address value. So I was wondering where exactly do string constants like the 'Hello' string above, get stored in memory? Because it almost seems like if it is a different section than primative data types then maybe this magical area isn't set up right for my OS. I could be crazy but if anyone knows the answer I'd love to listen. Thanks again everyone for all the help.
Thanx,
Nicole
I'm sorry I left out the:
address = address + 2;
line in the code I posted, I do have it in my source files though. I have also tried the suggested method of manipulating the char* like an array:
char *string = "Hello";
int i = 0;
int address = 0xB8000;
while ( string[i] != '\0' )
{
print_char( string[i], address)
i++;
address = address + 2;
}
But that still doesn't work, It just prints one blank at the location of the original address value. So I was wondering where exactly do string constants like the 'Hello' string above, get stored in memory? Because it almost seems like if it is a different section than primative data types then maybe this magical area isn't set up right for my OS. I could be crazy but if anyone knows the answer I'd love to listen. Thanks again everyone for all the help.
Thanx,
Nicole
RE:char * representation
Ok, thats odd.
try this:
char * string = "Hello";
char * addr = (char *) 0xb8000;
int i;
for(i = 0; i < 5; i++) {
addr[0] = string[i];
addr[1] = 7;
addr += 2;
}
If that doesn't work then for some reason, as you say, there's a problem with how you're setting up you segmentation. I'm no guru with this stuff, but that would seem the obvious problem. Hope this helps.
try this:
char * string = "Hello";
char * addr = (char *) 0xb8000;
int i;
for(i = 0; i < 5; i++) {
addr[0] = string[i];
addr[1] = 7;
addr += 2;
}
If that doesn't work then for some reason, as you say, there's a problem with how you're setting up you segmentation. I'm no guru with this stuff, but that would seem the obvious problem. Hope this helps.
RE:char * representation
Regarding your last post, I'm not quite sure why you set the:
char * addr = (char *) 0xb8000;
b/c doesn't the for loop overwrite that value? And if not, how and what do I do with addr then? Thanks for all the help.
Thanks,
Nicole
P.S. Sorry if the answer is painfully obvious and I'm just not getting it
char * addr = (char *) 0xb8000;
b/c doesn't the for loop overwrite that value? And if not, how and what do I do with addr then? Thanks for all the help.
Thanks,
Nicole
P.S. Sorry if the answer is painfully obvious and I'm just not getting it
RE:char * trouble??
Hi Nicole,
try this out......
char str[20] = "Hello, World!";
char *x;
unsigned long scr;
scr = 0xb8000;
while ( *x )
{
print_char(*x, scr);
x = x + 1;
scr += 2;
}
I guess this should work!!!.
Regards,
Ghadi
try this out......
char str[20] = "Hello, World!";
char *x;
unsigned long scr;
scr = 0xb8000;
while ( *x )
{
print_char(*x, scr);
x = x + 1;
scr += 2;
}
I guess this should work!!!.
Regards,
Ghadi
RE:char * trouble??
Hi Nicole,
Try this ...........
char str[20] = "Hello, World";
char *x = str;
char *addr = 0xb8000;
while ( *x )
{
print_char(*x, addr);
x = x + 1;
addr += 2;
}
Regards,
Ghadi.
Try this ...........
char str[20] = "Hello, World";
char *x = str;
char *addr = 0xb8000;
while ( *x )
{
print_char(*x, addr);
x = x + 1;
addr += 2;
}
Regards,
Ghadi.
RE:char * representation
Hi,
R u using djgpp or linux gcc?
if so then the answer is this.....
When the compiler generate the code it will be on to the code segment and if u don't hve the reallocating stub code (like in elf or COM format file) it will b a mess.
So manually u have to reallocate the strings to the DS segment from CS, and give that address. Also these compilers will consider DS = SS, so u got to set equal value 4 DS(data seg) & SS(stack seg). If not u may find with several other problems.
rgds,
YogaRamanan.T
R u using djgpp or linux gcc?
if so then the answer is this.....
When the compiler generate the code it will be on to the code segment and if u don't hve the reallocating stub code (like in elf or COM format file) it will b a mess.
So manually u have to reallocate the strings to the DS segment from CS, and give that address. Also these compilers will consider DS = SS, so u got to set equal value 4 DS(data seg) & SS(stack seg). If not u may find with several other problems.
rgds,
YogaRamanan.T
RE:char * trouble??
is *str global or local? if it is local, then ss should equal ds. try making *str global, then
RE:char * representation
Thanks everyone for their help,
I had a question about what Ramanan wrote. I am using linux gcc and I didn't quite understand
what the consequences are for doing that. For example do I need to declare my static strings
elsewhere. I don't think I'm quite understanding how to move my data to the data segment and what
it means to have the DS = SS. For the record I am declaring the string globally and passing it to a C function
called print that takes a char * and a starting address as parameters.
extern void print_char (char, int );
main()
{
char *word = "Hello";
int address = 0xB8000;
print ( word, address );
while(1)
{
// loop forever
}
}
void print (char *str, int addr)
{
int i =0;
while ( str[i] != '\0' )
{
print_char ( str[i], addr ); // This is my assembly function
i++;
addr = addr + 2;
}
}
My selectors in the GDT all have base = 0 and a limit = fffff. And my DS = SS = a data selector.
So if that helps diagnose why the string "word" can't seem to be printed out please let me know. Once
again thanks to everyone that has been so helpful
Thanx,
Nicole
I had a question about what Ramanan wrote. I am using linux gcc and I didn't quite understand
what the consequences are for doing that. For example do I need to declare my static strings
elsewhere. I don't think I'm quite understanding how to move my data to the data segment and what
it means to have the DS = SS. For the record I am declaring the string globally and passing it to a C function
called print that takes a char * and a starting address as parameters.
extern void print_char (char, int );
main()
{
char *word = "Hello";
int address = 0xB8000;
print ( word, address );
while(1)
{
// loop forever
}
}
void print (char *str, int addr)
{
int i =0;
while ( str[i] != '\0' )
{
print_char ( str[i], addr ); // This is my assembly function
i++;
addr = addr + 2;
}
}
My selectors in the GDT all have base = 0 and a limit = fffff. And my DS = SS = a data selector.
So if that helps diagnose why the string "word" can't seem to be printed out please let me know. Once
again thanks to everyone that has been so helpful
Thanx,
Nicole
RE:char * trouble??
Thanks everyone for their help,
I had a question about what Ramanan wrote. I am using linux gcc and I didn't quite understand
what the consequences are for doing that. For example do I need to declare my static strings
elsewhere. I don't think I'm quite understanding how to move my data to the data segment and what
it means to have the DS = SS. For the record I am declaring the string globally and passing it to a C function
called print that takes a char * and a starting address as parameters.
extern void print_char (char, int );
main()
{
char *word = "Hello";
int address = 0xB8000;
print ( word, address );
while(1)
{
// loop forever
}
}
void print (char *str, int addr)
{
int i =0;
while ( str[i] != '\0' )
{
print_char ( str[i], addr ); // This is my assembly function
i++;
addr = addr + 2;
}
}
My selectors in the GDT all have base = 0 and a limit = fffff. And my DS = SS = a data selector.
So if that helps diagnose why the string "word" can't seem to be printed out please let me know. Once
again thanks to everyone that has been so helpful
Thanx,
Nicole
I had a question about what Ramanan wrote. I am using linux gcc and I didn't quite understand
what the consequences are for doing that. For example do I need to declare my static strings
elsewhere. I don't think I'm quite understanding how to move my data to the data segment and what
it means to have the DS = SS. For the record I am declaring the string globally and passing it to a C function
called print that takes a char * and a starting address as parameters.
extern void print_char (char, int );
main()
{
char *word = "Hello";
int address = 0xB8000;
print ( word, address );
while(1)
{
// loop forever
}
}
void print (char *str, int addr)
{
int i =0;
while ( str[i] != '\0' )
{
print_char ( str[i], addr ); // This is my assembly function
i++;
addr = addr + 2;
}
}
My selectors in the GDT all have base = 0 and a limit = fffff. And my DS = SS = a data selector.
So if that helps diagnose why the string "word" can't seem to be printed out please let me know. Once
again thanks to everyone that has been so helpful
Thanx,
Nicole
RE:char * trouble??
As a matter of fact, you did *not* declare word as global.
extern void print_char (char, int );
char *word = "Hello"; // now it's global! try this
main()
{
int address = 0xB8000;
print ( word, address );
while(1)
{
// loop forever
}
}
void print (char *str, int addr)
{
int i =0;
while ( str[i] != '\0' )
{
print_char ( str[i], addr ); // This is my assembly function
i++;
addr = addr + 2;
}
}
extern void print_char (char, int );
char *word = "Hello"; // now it's global! try this
main()
{
int address = 0xB8000;
print ( word, address );
while(1)
{
// loop forever
}
}
void print (char *str, int addr)
{
int i =0;
while ( str[i] != '\0' )
{
print_char ( str[i], addr ); // This is my assembly function
i++;
addr = addr + 2;
}
}
RE:char * representation
Hi,
Here is the code to move static string from CS to DS to use.
char *tostr(char *str)
{
asm volatile("cld \n\t \
push %%ds \n\t \
push %%es \n\t \
mov %%ds, %%ax \n\t \
mov %%ax, %%es \n\t \
mov %%cs, %%ax \n\t \
mov %%ax, %%ds \n\t \
push %%esi \n\t \
xor %%ecx, %%ecx \n\t \
start: lodsb \n\t \
inc %%ecx \n\t \
or %%al, %%al \n\t \
jz finished \n\t \
jmp start \n\t \
finished: pop %%esi \n\t \
rep movsb \n\t \
pop %%es \n\t \
pop %%ds \n\t" \
::"S"(str), "D"(str) \
);
return str;
}
Now what u have do is just call this function before passing to the print function.
int main()
{
int address = 0xB8000;
print(tostr("Ramanan"),address);
// or like this
char *str = tostr("Hello Ramanan");
print(str,address);
return 0;
}
i think this may help u. Make sure DS = SS (i think u already did this).
rgds,
YogaRamanan.T
Here is the code to move static string from CS to DS to use.
char *tostr(char *str)
{
asm volatile("cld \n\t \
push %%ds \n\t \
push %%es \n\t \
mov %%ds, %%ax \n\t \
mov %%ax, %%es \n\t \
mov %%cs, %%ax \n\t \
mov %%ax, %%ds \n\t \
push %%esi \n\t \
xor %%ecx, %%ecx \n\t \
start: lodsb \n\t \
inc %%ecx \n\t \
or %%al, %%al \n\t \
jz finished \n\t \
jmp start \n\t \
finished: pop %%esi \n\t \
rep movsb \n\t \
pop %%es \n\t \
pop %%ds \n\t" \
::"S"(str), "D"(str) \
);
return str;
}
Now what u have do is just call this function before passing to the print function.
int main()
{
int address = 0xB8000;
print(tostr("Ramanan"),address);
// or like this
char *str = tostr("Hello Ramanan");
print(str,address);
return 0;
}
i think this may help u. Make sure DS = SS (i think u already did this).
rgds,
YogaRamanan.T
RE:char * trouble??
Thanks for the advice guys,
Well I tried your suggestions and here is what happened:
1) Ramanan's function didn't seem to work but it could be because there were several compilation warnings and I haven't looked over the code personally. But I will soon and thank you for the function.
2) Adek, I stand corrected about the global declaration, I tried to use the function with an actual globally declared string and it, well, kind of worked. It printed about 10 lines of garbage to the screen with the actual string "Hello" printed at the very end. This seems very particular to me and I can't seem to understand why this would happen. If you guys have any ideas why a global string would be preceded by several lines of garbage and a locally declared string wouldn't work with the function at all, I'd like to pick your brain. Thanks again guys, you're a lifesaver.
Thanx,
Nicole
Well I tried your suggestions and here is what happened:
1) Ramanan's function didn't seem to work but it could be because there were several compilation warnings and I haven't looked over the code personally. But I will soon and thank you for the function.
2) Adek, I stand corrected about the global declaration, I tried to use the function with an actual globally declared string and it, well, kind of worked. It printed about 10 lines of garbage to the screen with the actual string "Hello" printed at the very end. This seems very particular to me and I can't seem to understand why this would happen. If you guys have any ideas why a global string would be preceded by several lines of garbage and a locally declared string wouldn't work with the function at all, I'd like to pick your brain. Thanks again guys, you're a lifesaver.
Thanx,
Nicole