Page 1 of 2
Problem is strings
Posted: Sat Jun 24, 2006 8:36 pm
by AlgorithmX2
Hi Im new to these parts and im just trying some stuff out and getting used to things, I wrote a bootloader that loads some small c code that just does some stuff with the screen, turns it blue, and puts a border on it, but I wanted to have it write out text, well its easy if I do it 1 at a time manually, but if I try to use the string method it fails as if the pointer is wrong. if I manually locate the data based on where I loaded it + the offset in the compiled object, then it works fine, so I know its there. any idea why the pointer would be wrong? heres a sample of what im trying to do...
const char *Msg="This is my TEST";
Print(Msg, 0x2F, 8, 10, 14);
// String, color stuff, x, y, strlen
void Print( const char *a, unsigned char b, int x, int y, int bx)
{
unsigned char *vidmem = (unsigned char *)0xB8000;
long lx=0;
while (lx<bx)
{
vidmem[2*(lx+x+y*80)] = a[lx];
vidmem[2*(lx+x+y*80)+1] = b;
lx++;
}
}
im using GCC for my c 'kernel' and NASM on the bootloader
Any ideas whats causeing this?
Posted: Sat Jun 24, 2006 9:12 pm
by chase
Only guess would be that you segment descriptors are incorrect or even you A20 code could be off depending on where you are loading things. Both wild guesses. What really helped me at this stage was writting a binary integer to asciihex routine. Instead of trying to print Msg, try printing its address and see if where you'd expect it to be.
You'll also want a print binary to screen and jmp $ routine. Exremely useful when you have to start debuging your triple faults
Posted: Sat Jun 24, 2006 10:28 pm
by AlgorithmX2
As you suggested I have written a HexPrint routine and it is quite a bit of help, according to my tests my pointer is pointing to 0xF000FF53 when it should be pointing to 0x2860... any idea how can I fix this?
sorry I'm not very familiar with all the asm termanology and its some what difficult for me to find good sources of information on the internet where I can learn about it.
Posted: Sat Jun 24, 2006 10:40 pm
by chase
Well the compiler/linker is making assumptions about where this code is located in memory. First you have to make sure you are linking everything in the correct order with the correct arguments. All depends on what format your using and where in memory you're putting things, take a look at the linking I'm doing
http://www.osdev.org/howtos/1/ in here to see if it's any help.
You might also want to compile to assembly and verify that the hex number you've got now is what is really in the code. The -S option to gcc will compile to assemble, it'll be At&t gas syntx where everything is swapped but you should be able to figure out what is going on.
Posted: Sat Jun 24, 2006 10:44 pm
by chase
If you need some assembly stuff to learn from I'd take a look at
http://webster.cs.ucr.edu/AoA/DOS/AoADosIndex.html
Posted: Sat Jun 24, 2006 11:49 pm
by AlgorithmX2
Thank you for the link that will definitley come in handy, i've found pages from that text, but I was unable to find the full thing.
hmm about the Linking, Im useing -Ttext to specifiy where the code will be run from in memory.
A quick summery is that im loading the sector into 0x2200 and I use ld -i -Ttext 0x2200 -o kernel.o main.o to link .
Changeing my -Ttext location does not affect the pointer, then again im not sure if it should, but if that would be the cause I can assume, that something was suppost to happen.
Also I have done another test where I did a test on a local string, and the pointer in this case appears to be NULL which to me dont make much sence at all, at least to me.
This makes me think maybe Its something in the asm before I load up the 'kernel' code? perhapes I need to set a register or a messed something else up while looking for my code on the HDD?
I'm still working at it but im seeing little progress, good thing I have some free time!
at least im darn persistent, with out that I would never haven even got the darn kernel to load off a real harddrive.
thanks for all the help so far!
Posted: Sun Jun 25, 2006 2:28 am
by AlgorithmX2
I have made a rather bizare discovery,
unsigned char Values[]={'b','o','b',' ',0};
and
unsigned char Values[]="bob";
when used, the first works perfectly, while the second fails completely.
I'm still working at it and maybe i'll figure it out, just thought I'd give an update on my situation...
as this particular test was using local varibles, I belive that this is because the first is useing the Stack, which is working fine, and the second is useing a set of data stored in a group else where, if some one could confirm or correct me I would be most grateful. any way, back to work I go...
Posted: Sun Jun 25, 2006 11:43 am
by chase
AlgorithmX2 wrote:I have made a rather bizare discovery,
unsigned char Values[]={'b','o','b',' ',0};
and
unsigned char Values[]="bob";
when used, the first works perfectly, while the second fails completely.
I'm still working at it and maybe i'll figure it out, just thought I'd give an update on my situation...
as this particular test was using local varibles, I belive that this is because the first is useing the Stack, which is working fine, and the second is useing a set of data stored in a group else where, if some one could confirm or correct me I would be most grateful. any way, back to work I go...
Which makes me think you data segements aren't setup correctly.... Assuming you're using GCC, it does some weird things with strings sometimes. Look at the GCC docs, there are some options to control what segement your constant strings end up in.
Posted: Sun Jun 25, 2006 2:18 pm
by AlgorithmX2
I've been searching for gcc options, ld options, even objcopy options, I couldn't find anything that had to do with constants,
Also I have the asm output of gcc sitting in front of me, and its the most ugly thing I have ever seen, It uses instructions I have never seen and to me looks backwards.
But I dont mean to complain, I just have no idea where to go from here.
I tried compileing the bootloader/'kernel' from
http://www.osdever.net/tutorials/brunma ... ial_03.php because it basically does what I want to do, and unfortunely when I run it, it just hangs.
the only progress I have made is that i found out that when I try to access any globels it seems the value is always 0xF000FF53, it dosn't matter if its an int, or a char*, and I dont know what this means but I bet it is some what signifigant.
I've tried altering values all over the place, I've tried moveing the whole program to some where else in memory, none of which has had any effect at all.
I just did a test where I examined the memory address of a globel int, and a the location of the pointer, to the string, it says that the int, should be located at the 0x0000 and the pointer to the string should be at 0x0004 which is defneitly wrong, the problem being however is that I dont know how to change it.
when you say, that theres somethin wrong with my data segements, do you mean that its in the wrong place or something?
Posted: Sun Jun 25, 2006 2:47 pm
by Midas
String constants are stored before the function in which they are used, unless you pass the -fwritable-strings option to GCC.
I don't know if this helps, or not. I don't see why all constants would yield the same pointer address, however.
Posted: Sun Jun 25, 2006 3:22 pm
by AlgorithmX2
well I tried useing it, gcc spit it back at me saying its depreciated, when I did some research it said that they stoped support in the newer version, so that didn't get my anywhere, thanks for tryin tho.
I figured I would put some hard evidence up on here
so here it is
const char*Msg="This is my TEST";
int main()
{
char A[]={'T','e','s','t','O','S','\0'};
char B[]={"bob"};
char C[]={'b','o','b',' ',0};
Print(A, 0x2F, 8, 8, 6); -> prints "TestOS",
Print(B, 0x2F, 8, 9, 15); -> prints S (weird ascii = with thirdline)TestOS
Print(C, 0x2F, 8, 10, 3); -> prints bob
PrintHex(A,8,11); -> prints 0x0008FFD4
PrintHex(B,8,12); -> prints 0x0008FFD0
PrintHex(C,8,13); -> prints 0x0008FFB4
Print(Msg, 0x2F, 8, 15, 15); -> prints blanks
PrintHex(Msg,8,16); -> prints 0xF000FF53
}
maybe this view of the information will help everyone understand whats going on more, or at least its more organized this way then in my constant rambleming.
Posted: Sun Jun 25, 2006 5:53 pm
by AlgorithmX2
After much banging of the head upon the keyboard, hehe
a thought crossed my mind, what if its the compiler...
it was...
I downloaded the current version of DJGPP, ploped it on in, compiled it, worked perfectly on the first shot... well at least theres a happy ending, happy codeing folks!
Posted: Sun Jun 25, 2006 7:41 pm
by chase
AlgorithmX2 wrote:After much banging of the head upon the keyboard, hehe
a thought crossed my mind, what if its the compiler...
it was...
I downloaded the current version of DJGPP, ploped it on in, compiled it, worked perfectly on the first shot... well at least theres a happy ending, happy codeing folks!
Think I had the same thought at the same time.
I'm trying Cygwin gcc instead of DJGPP but what I'm seeing in the generated code(assembly made with -S) is that Cygwin gcc seems to be making standard null terminated strings but gcc on linux seems to be making some type of string objects that don't end in nulls. It's very bizarre and I'm not positive it's the reason for the problem or how to change the behavior.
I'll investigate in more some time this week. What compiler/version/OS combination where you using when it was broken?
Posted: Sun Jun 25, 2006 8:14 pm
by AlgorithmX2
I belive it was something like mingw gcc/ 3.4.2 / winxp
Posted: Mon May 07, 2007 6:52 am
by chromex
Just in case any else runs across this thread looking for the solution to this problem but is unwilling/unable to switch away from gcc the key lies in using gcc version 2.95 before they put in certain optimizations which break this.