In the the for loop:
for (ch = str, i = 0; *ch; ch++, i++)
vidmem[i] = (unsigned char) *ch | 0x0700;
the condition portion *ch
instructs the C compiler to continue looping while the expressions is true(non-zero). As long as *ch
is not a NUL(\0) terminating character the expression will be true and will continue looping. When it reaches a character that is zero the conditional expression will be false and the loop exits. Effectively it loops through a string until it reaches the NUL terminating character.
The reason for your crash with vidmem[i] = (unsigned char) *ch | 0x0700;
is because vidmem
was given the video memory address 0xb8000. This memory is not accessible to a Win32 based application and the OS (Windows) will fault your application and display the error message about the program no longer working.
The only way to resolve this is compile it in such a way that it can be used as an MS-DOS program:
- Compile with 16-bit C compiler and run it in MS-DOS or an MS-DOS emulator like DosBox
- Compile it into your kernel and test it in a bare metal environment (QEMU, Virtualbox, VMWare etc.)
*ch | 0x0700
takes the current character and bitwise ORs it to 0x0700. That effectively creates a 16-bit word with the character in the lower 8 bits and 0x07 in the upper 8 bits.
This is done because every character you see on standard color text video modes that use memory region 0xb8000 is made up of 2 bytes (one 16-bit word). This is described in a Wikipedia article:

If the current character being processed in the loop is the letter H (0x48) then *ch | 0x0700
would become 0x0748 which is then stored at a particular memory location on the video display.
You may wish to read about bit manipulation in C. I found this tutorial that may help.