-1

I have a function called kmain(), which just has 1 variable: vidmem. This is a char* type variable (one character), but i want it to be a string.
This is my code at the moment:

kmain()
{
    char* vidmem=(char*)0xb8000;
    vidmem[0] = 'A';
    vidmem[1] = 0x04;
}

As explained before, this variable is just one character: A. How can I make this a string, i.e. Hello, World!?

intmain
  • 11
  • 2
  • `strcpy(vidmem,"Your string you want");` – 12431234123412341234123 Dec 23 '20 at 17:25
  • But please be aware that `vidmem` does not expect a string. It expects a character-color table where a byte (or `char`) is for a character and the next byte is for the color of that character. You have to write your own print function for that that sets every second byte to the next character of the source string. – 12431234123412341234123 Dec 23 '20 at 17:30
  • @12431234123412341234123 `strcpy(vidmem, "Your string you want");` is begging for a segfault. The memory does not belong to the program yet. – Captain Trojan Dec 23 '20 at 17:32
  • @CaptainTrojan No `vidmem` is a region freely accessible by the OPs program. The Program does not run on a OS. Writing to `vidmem` is the intended way to print something to the screen in this environment. See https://wiki.osdev.org/Printing_To_Screen – 12431234123412341234123 Dec 23 '20 at 17:42
  • Your question misses a lot of essential information, as you can see by the people who misunderstood your problem. You have to mention that you do not run a user-space program but a kernel-space program right after booting a x86 machine. – 12431234123412341234123 Dec 23 '20 at 17:44
  • See also https://stackoverflow.com/questions/33681795/how-to-write-to-screen-with-video-memory-address-0xb8000-from-real-mode – 12431234123412341234123 Dec 24 '20 at 15:27

3 Answers3

2

Others explained to you how to get a string, which was your question. However, this is not your problem. You use the x86 and want to write to the text buffer at 0xB8000 to show a text on the screen. This is not normal, since most other program on x86 run inside an OS.

To get what you want, you have to set every second byte to the character you want and every other byte to the color you want. A string will not work for your problem.

Means you will need something like this:

#define COLOR 0x04  //red text on black background
vidmem[0] = 'A';
vidmem[1] = COLOR;
vidmem[2] = 'B';
vidmem[3] = COLOR;
vidmem[4] = 'C';
vidmem[5] = COLOR;

Of course it would make more sense to do this in a for or while loop and don't do it by hand, but i want to explain what you need to do in order to print some text.

Indexing Positions

You can directly accessing individual positions on the screens. vidmem is an array of 25 lines, each line is an array of positions, each position has a byte for the symbol and one for the color. You can change your vidmem declaration so you see at a glance what you access.

#define COLOR 0x04
void kmain(void)  //also, use a proper declaration, with return type.
{
    //vidmem is a pointer to an array with 50 elements of an array of 2 elements with type char
    //The array [50][2] is exaclty the same as an array of [100], but 
    //with [50][2] we tell the compiler how to access it. 
    //The memory pointed to by vidmem has a special hardware function, so it should be volatile.
    volatile char (*vidmem)[50][2]=(void*)0xb8000; 
    //                      ^----- 50 columns per line
    //                          ^-  2 bytes per character

    //     V---------------  Line
    //        V------------  Column
    //           V---------  Symbol (0) or color (1)
    vidmem[0][0][0] = 'A';   //symbol at position 0,0 is a 'A'
    vidmem[0][0][1] = COLOR; //Set color for position 0,0
    vidmem[0][1][0] = 'B';   //symbol at position 0,1 is a 'B'
    vidmem[0][1][1] = COLOR; //Set color for position 0,1
    //you can also directly access any other position
    vidmem[1][0][0] = 'C';   //symbol at position 1,0 (second line) is a 'C'
    vidmem[1][0][1] = COLOR; //Set color for position 1,0
}
0

Strings in C are null-terminated sequences of bytes. A char * points to the beginning of this sequence. Such sequence, as I've said, must end with a \0 symbol, the NUL symbol. So if you want to extend your code to make vidmem contain Hello World, you can do something like:

char vidmem[64];     // stack memory allocation (64 bytes)
vidmem[0] = 'H';
vidmem[1] = 'e';
vidmem[2] = 'l';
...
vidmem[11] = 'l';
vidmem[12] = 'd';
vidmem[13] = '!';
vidmem[14] = '\0';   // very important

And now you can

printf("%s", vidmem);

to observe

Hello, world!
Captain Trojan
  • 2,800
  • 1
  • 11
  • 28
  • But how do you keep the `vidmem[1] = 0x04`? This is an important part too. – intmain Dec 23 '20 at 17:27
  • @intmain You can just call `vidmem[0] = 'A'`, then `vidmem[1] = 0x04`, and then `vidmem[2] = '\0'`. A null-terminated string. – Captain Trojan Dec 23 '20 at 17:28
  • I have found the answer, which is putting `vidmem[index_location] = 0x04` after every character in the array, like this: `vidmem[0] = 'A';` `vidmem[1] = 0x04;`, etc. I'll accept this answer tho, because it helped me the most. – intmain Dec 23 '20 at 17:34
  • I think you misunderstood the OP's problem. To be fair, he himself misunderstands it and the question is not as precise as it should be. The bytes after `0xB8000` define what is shown on the terminal when the OS starts running. Replacing it with a automatic variable defeats the purpose. – 12431234123412341234123 Dec 23 '20 at 17:35
  • @12431234123412341234123 I believe understanding own problems is a good prerequisite for posting on SO. I could go guessing what OPs mean by what they type, but that's not very efficient. – Captain Trojan Dec 23 '20 at 18:07
  • @CaptainTrojan Writing to special addresses is a very common thing to access special hardware features. – 12431234123412341234123 Dec 24 '20 at 13:55
  • @12431234123412341234123 That's what you might know, but not other SO users, who have no idea that OP actually refers to setting special hardcoded memory values to which he actually has access to. Although I admire your ability to deduce this fact from the keywords `kmain` and `vidmem`, I'm afraid mere mortals such as I could try to apply your solution to their own problems and fail. – Captain Trojan Dec 24 '20 at 14:54
  • 1
    @CaptainTrojan The OP sets the pointer to a special address, what did you think why he is doing this? A short search for "0xB8000" reveals his platform. There is even a whole Wikipedia article about it (https://en.wikipedia.org/wiki/VGA_text_mode). Most hardware features on most controllers and processors are access by writing or reading from special addresses, it is not something extraordinary special that exist only on a few platforms. – 12431234123412341234123 Dec 24 '20 at 15:34
0

A string is a contiguous sequence of characters terminated by a null character, for purposes of C standard library functions, per clause 7.1.1 paragraph 1 of the 2018 C standard. To make a string with the characters 'A' and 0x04, simply put a zero byte after them.

That said, char* vidmem(char*)0xb8000; is not correct C syntax. Perhaps you meant char *vidmem = (char *) 0xb8000;. This is a definition that might be used in special circumstances (different from general-purpose multi-user environments) to define a pointer to a designated place in memory. However, the name vidmem suggests this might be video memory. A character string is an unusual thing to have in video memory. This code may not be doing what you intend.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • Yes, you have guessed it right. I meant `char* vidmem=(char*)0xb8000`. I've ran this code multiple times, and yes, it does what i intend. – intmain Dec 23 '20 at 17:26
  • @intmain: The fact that your program produces the output you expect in some experiments is not conclusive proof that the source code does what you intend. – Eric Postpischil Dec 23 '20 at 17:27
  • `vidmem` expects characters and shows them on the terminal. But it is not a string, it expects a color in every second byte. See https://wiki.osdev.org/Printing_To_Screen – 12431234123412341234123 Dec 23 '20 at 17:31