From: <ce...@ar...> - 2006-04-07 00:24:55
|
On Wed, Apr 05, 2006 at 11:03:16PM -0400, Frank Kotler wrote: > You're on the right track here. *Now* the problem is that ds is involved > (I spoke too soon, above) - "lds si, [ds:ptr]" is what is implied here > (you wouldn't want to write it that way, or Nasm would emit a redundant > segment prefix, but that's what it "means"). I just realized why it won't work (and truly, I feel like a moron for wasting your time on it) -- the assembler doesn't know that the code's going to be loaded into 7c00 without my say-so. That's my entire problem right there. > Not sure why you'd "shr eax, 16" - "shr eax, 4" would've been closer... > but that won't really do it... might if you're lucky... and "seg" is for > linkable object formats... "-f bin" doesn't have "segments" in the same > sense. We can say "segment .text" or "section .text" - exactly the same > thing to Nasm, but I prefer the latter. Nasm re-arranges our "sections" > (.text first, .data next, .bss last), but they aren't put in separate > "segments"... I was skeptical, so I ran it -- shr eax, 4 doesn't work. My reasoning for 16 was that if message's absolute address is 00007c03, then 0000 should be in the segment register and 7c03 should be in the index. > And put it in ds. Sure enough, 0000:7C03 is where the message lives! > "message" just evaluates to 3, since Nasm defaults to "org 0" if you > don't specify. That would be okay, too - but we would want to load ds > with 7C0h in that case. 07C0:0003 is the *same* address! I might be misunderstanding, but my attempt at setting up the address as 07c0:0003 isn't pointing at the right place. Again, my understanding was that the segment and index are discrete parts of the 32 bit address where the message is located. Is that incorrect? I tried this: mov si, 0x0003 mov ax, 0x07c0 mov ds, ax call putstr Going with the assumption that you meant 7c00 instead of 07c0 doesn't work either. My understanding appears to be correct here that ds specifies the upper 16 bits of the memory access and si specifies the lower 16 bits. > Okay... no "org", so we've got "org 0". The "other way" (more common, > perhaps) is "org 7C00h"... we just need to do something different with > ds. The bios does *not* set it up for us! So let's run with this. The data I want is in code space. In order to execute the code, cs ought to be set correctly. So if I run: mov si, message mov ax, cs mov ds, ax call putstr message shows up as 0x0003 in this case, which makes sense given that the assembler doesn't know that the BIOS is going to throw this code into 0x7c00. It appears to me that since the proper segment is 0x0000, I'll need to find out what my initial address is and use that as a base for all my accesses. This may be entirely crazy, but I'm calling a function, popping bx, subtracting the size of the call instruction from bx, and making all references to data as bx+variable, though I apparently can't do that outside of a dereference. Is there a better way to go than mov si, bx / add si, message? > Okay... you may have done yourself a favor here. The "canonical" > bootsector starts with either a "jmp" (near), or "jmp short ..."/"nop", > and the "oem string" starts after that. I've never seen it, but I've > heard of a bios that refuses to boot without it. What you jump over is > up to you - there are advantages to making your disk FAT12 compatible... Interesting. I hadn't heard that before. I knew there was a signature on the bootsector that was required, but that's it. I've been against that method just because of the additional jump. Thanks 8) > Maybe want to load other segregs here too. In particular, you'll want to > know where your stack is! Presumably, the bios has got ss:sp pointed > someplace "sane" - interrupts, the timer and stuff, use the stack, so we > *can't* have it pointed where it'll scribble on important stuff, even if > we don't use it. Best get it under our control, ASAP. (but for this > example... ignore the issue :) The system in hand has ss=0, sp=0xFFFE which is sufficient for the moment. > This only stays "hlt"ed until an interrupt occurs. You might want to do: > > stop: > hlt > jmp stop > > Another possibility... "int 19h" reloads the bootsector... you might > want to "wait for a key", and then "int 19h" to "see it again" for > debugging purposes (doesn't help that much...). ATM, the hlt is there until I go on to bigger and better things. I'm satisfied with trying to make putstr work for the moment ; ) In my case, I've been running this via bochs (which seems to mimic the real system in all the important ways), so rebooting's really nice & easy. > *Some* video biosen (I'm told) use bl as the "attribute" (color) to use. > Most use the default white-on-black (7). More commonly, bh is used as > the "video page" to write to - other biosen write to whatever page is > "current" (0, ... "always", AFAIK). My bios writes white-on-black to the > current page regardless of what's in bx. For "maximum safety", I'd go > with "mov bx, 7". No need to use ebx. I was purposely aiming for 0 on the theory that I can read what the BIOS prints, so current can't be too bad a choice. 7 is sensible though. I'll keep that in mind. Lest it doesn't come out through this email, thanks a ton for helping me out. The subsequent explanations beyond "NASM can't know a priori where the code is being loaded" are well beyond your duties as a maintainer. -Phil/CERisE |