Page 1 of 2

char * trouble??

Posted: Tue Sep 16, 2003 11:00 pm
by nicky_girl
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
    

RE:char * trouble??

Posted: Tue Sep 16, 2003 11:00 pm
by Squrky
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 :)

RE:char * trouble??

Posted: Tue Sep 16, 2003 11:00 pm
by Squrky
Bother.

replace
print_char(str[idx], 0xb8000 + idx);

with
print_char(str[idx], 0xb8000 + idx * 2);

Sorry about that :).
    
    

RE:char * representation

Posted: Tue Sep 16, 2003 11:00 pm
by nicky_girl
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

RE:char * representation

Posted: Tue Sep 16, 2003 11:00 pm
by Squrky
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.

RE:char * representation

Posted: Wed Sep 17, 2003 11:00 pm
by nicky_girl
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 :)

RE:char * trouble??

Posted: Wed Sep 17, 2003 11:00 pm
by Ghadi
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

RE:char * trouble??

Posted: Wed Sep 17, 2003 11:00 pm
by Ghadi
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.

RE:char * representation

Posted: Thu Sep 18, 2003 11:00 pm
by Ramanan
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

RE:char * trouble??

Posted: Thu Sep 18, 2003 11:00 pm
by Adek336
is *str global or local? if it is local, then ss should equal ds. try making *str global, then

RE:char * representation

Posted: Thu Sep 18, 2003 11:00 pm
by nicky_girl
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

RE:char * trouble??

Posted: Thu Sep 18, 2003 11:00 pm
by nicky_girl
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

RE:char * trouble??

Posted: Fri Sep 19, 2003 11:00 pm
by Adek336
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;
        }
    }

RE:char * representation

Posted: Fri Sep 19, 2003 11:00 pm
by Ramanan
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

RE:char * trouble??

Posted: Fri Sep 19, 2003 11:00 pm
by nicky_girl
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 :)