Hello,
I'm doing a simple OS, that will capture a inputted character and will print it using a procedure that I've done(because I will print many things later). At the time it's like this:



jmp short main   ; Jump past disk description section
nop              ; Pad out before disk description

; ------------------------------------------------------------------
; Disk description table
; Values are those used by IBM for 1.44 MB, 3.5" diskette

OEMLabel            db "LEAFOS"  ; Disk label - 8 chars
BytesPerSector      dw 512       ; Bytes per sector
SectorsPerCluster   db 1         ; Sectors per cluster
ReservedForBoot     dw 1         ; Reserved sectors for boot record
NumberOfFats        db 2         ; Number of copies of the FAT
RootDirEntries      dw 224       ; Number of entries in root dir
LogicalSectors      dw 2880      ; Number of logical sectors
MediumByte          db 0F0h      ; Medium descriptor byte
SectorsPerFat       dw 9         ; Sectors per FAT
SectorsPerTrack     dw 18        ; Sectors per track (36/cylinder)
Sides               dw 2         ; Number of sides/heads
HiddenSectors       dd 0         ; Number of hidden sectors
LargeSectors        dd 0         ; Number of LBA sectors
DriveNo             dw 0         ; Drive No: 0
Signature           db 41        ; Drive signature: 41 for floppy
VolumeID            dd 00000000h ; Volume ID: any number
VolumeLabel         db "LEAFOS"  ; Volume Label: any 11 chars
FileSystem          db "FAT12"   ; File system type: don't change!

; End of the disk description table
; ------------------------------------------------------------------


main:
   mov si, msg
   call printf
   
   mov ah, 00h
   int 16h
   
   jmp $
   

; +------------+
; | Procedures |
; +------------+    
printf:
   mov ah, 0eh
   mov bl, 07h

   .nextchar
      lodsb
      or al, al
      jz .return
      int 10h
      jmp .nextchar

   .return
      ret

.data
msg db "Test"                            
                           
times 510-($-$$) db 0
dw 0xAA55

As my procedure reads the SI and print it to the screen, but I want to know the correct way to do it. But I think that it's to move all the content of AL to a string(that I don't know how to declare it, because I've never declared 8-Bits variables, just db and dw) and the move it to the SI, then if I'm correct, I don't know how to declare the variable, then I will need to know how.

Best Regards,
Nathan Paulino Campos
Posted on 2010-05-27 18:10:59 by nathanpc
OK, so...
    mov ah, 00h
    int 16h
Puts a character into AL doesn't it? So could you not just

    ; ---- Get a key into AL----;
    mov ah, 00h
    int 16h
    ;---- Print what is in AL----;
    mov ah, 0eh 
    int 10h

???

Also about your code... How do you expect the keypress to get into SI? How do you plan to print it if you stop to JMP $ and don't continue? Were is you "msg" string at?
Posted on 2010-05-27 18:56:37 by Coty
Sorry, I've forgot to copy that part of the code, but now I fixed. Also, I don't want to do just that, because I need to use my procedure.
Posted on 2010-05-27 19:02:22 by nathanpc
After 4 keys the program will finish putting data into SI and go print with your routeene

   mov si, msg
   ;---- Get 4 keys ----;
   mov cx, 4
   ; ---- Get a key into AL----;
.wut:
   mov ah, 00h
   int 16h
   ;---- Put key into SI and do moar ----;
   stosb
   loop .wut
   ;---- Print what is in SI----;
  Call printf

stosb does the opisite of lodsb by putting what is in AL into SI instead of reading from SI and putting into AL ;)
Posted on 2010-05-27 19:25:54 by Coty
nathanpc,

You may already have noticed that nasm warns you about several lines. Two of them are real labels (.nextchar and .return), but .data Do you think it's directive? No, it's label too. You'd better use colon after label explicitly (and pay more attention to compiler warnings ;)).

For int 10h fn 0Eh it's much more important to have correct bh than bl: bh defines number of video page to output character (fortunately, in most cases BIOS starts boot sector with page 0 active and bh being equal to 0), bl is foreground character color for graphic modes only.

To use your procedure, you must pass correct parameter to it. As Coty said, int 16h can be used to get single keystroke from keyboard (it doesn't echo it, though).

BTW, 8 bits is a byte (and db stands for define byte). ;)

----8<----

After 4 keys the program will finish putting data into SI and go print with your routeene


Are you sure? lodsb copies contents of byte to al, so nothing else than "Test" will print. ;)
Posted on 2010-05-27 19:31:09 by baldr
I was hoping I edited it before any one saw that.
coty fail :lol:
Posted on 2010-05-27 19:43:51 by Coty

After 4 keys the program will finish putting data into SI and go print with your routeene

    mov si, msg
    ;---- Get 4 keys ----;
    mov cx, 4
    ; ---- Get a key into AL----;
.wut:
    mov ah, 00h
    int 16h
    ;---- Put key into SI and do moar ----;
    stosb
    loop .wut
    ;---- Print what is in SI----;
  Call printf

stosb does the opisite of lodsb by putting what is in AL into SI instead of reading from SI and putting into AL ;)

I tried to use it, but it haven't worked, I can't see the output of it. :(




nathanpc,

You may already have noticed that nasm warns you about several lines. Two of them are real labels (.nextchar and .return), but .data… Do you think it's directive? No, it's label too. You'd better use colon after label explicitly (and pay more attention to compiler warnings ;)).

For int 10h fn 0Eh it's much more important to have correct bh than bl: bh defines number of video page to output character (fortunately, in most cases BIOS starts boot sector with page 0 active and bh being equal to 0), bl is foreground character color for graphic modes only.

To use your procedure, you must pass correct parameter to it. As Coty said, int 16h can be used to get single keystroke from keyboard (it doesn't echo it, though).

BTW, 8 bits is a byte (and db stands for define byte). ;)

----8<----

After 4 keys the program will finish putting data into SI and go print with your routeene


Are you sure? lodsb copies contents of byte to al, so nothing else than "Test" will print. ;)

Yes, I've payed attention on the compiler warnings, but I put my code like that, because it's my style(as every has your personal style of writing codes), also I know about bh and bl, but I forgot that db was byte, but I was remembering that dw is for word. Thanks for advising me about this. :)
Posted on 2010-05-27 20:09:34 by nathanpc


After 4 keys the program will finish putting data into SI and go print with your routeene

    mov si, msg
    ;---- Get 4 keys ----;
    mov cx, 4
    ; ---- Get a key into AL----;
.wut:
    mov ah, 00h
    int 16h
    ;---- Put key into SI and do moar ----;
    stosb
    loop .wut
    ;---- Print what is in SI----;
  Call printf

stosb does the opisite of lodsb by putting what is in AL into SI instead of reading from SI and putting into AL ;)

I tried to use it, but it haven't worked, I can't see the output of it. :(


Do you understand why?

  • stosb uses es:di as the destination, yet it's uninitialized;

  • int 16/00 reads keystroke, it doesn't echo it to screen.

Posted on 2010-05-28 00:46:08 by baldr
About the int 16 AH=00h, I know that it doesn't echo it, and this is what I want, then I need to echo it, but now I was thinking about that other things of int 10, there was one cursor blinking thing, and if I'm remembering good there was one thing that what you type it echos, like MS-DOS and consoles does... :O
Posted on 2010-05-28 04:46:36 by nathanpc
Hallo! So, you have some code I gave you, but it is broken... and? From what I think the
current code only has 1 small error. easy fix. Google stosb and read what baldr
said. Shouldn't take more than an half hour to fix, once you accomplish you will
remember and all this will be easy. Sure you may hate me, but it will give you the chance
to get your feet wet and will give you a chance to learn how to solve problems. remember
each painful step on the way up will get you closer to the top  ;)

HINT: There is one line of code missing line, and it has something to do with "mov DI".
Posted on 2010-05-28 06:54:13 by Coty
like MS-DOS and consoles does...


Here you've said the key words. OS considers console as compound device consisting of input and output devices (usually keyboard and screen, but not always). DOS provides quite a lot of console input services, with or without echo.

BIOS, OTOH, knows nothing about consoles, so int 16 doesn't have functions that echo keystrokes they read and int 10 doesn't have functions to read keystrokes.
Posted on 2010-05-28 14:12:37 by baldr
Yeah... eventually you'll probably want to provide "get key with echo" and "get key without echo". The former is probably more useful, but it'll take a couple of bios calls.

Something that hasn't been mentioned is initialization of segment registers. If you're seeing "test", your bios is leaving ds, at least, set to zero. This isn't always true (if you want your code to work on other machines), I'd explicitly set ds and es to zero, right after "main". You might think about where your stack is, too. Often, it appears, bios leaves ss:sp pointed to very low memory - top of your IVT! You'll want it in a "known" place eventually (remember that interrupts are using your stack, as well as any use you may be making of it). If you know where it's eventually going to be, "right at first" is a good time to put it there.

Baldr points out that ".data" isn't a directive, but a local label. If you wanted a "segment directive", you could put one there. To Nasm, "segment" and "section" are aliases, but "segment" is misleading (IMHO) in a binary format - there are no "segments" in a flat binary format. But Nasm will put "section .text" (the default if you don't specify) first, "section .data" after that, and "section .bss" last. "section .data" isn't much use in a bootsector - if you *do* have one, make sure your padding and boot sig are at the end of it - not in "section .text"! Remember that "section .data" comes after "section .text". However, "section .bss" could be useful - it comes after ".text" (and/or ".data", if any), but doesn't add anything to your 512 byte file! It merely assigns names to memory beyond the 512 bytes. It is a possible place where you'd want to put your input buffer (resb BUFSIZ).

Please don't write "gets()"! Write "ngets()". Don't allow a "user" - even if it's you - to overflow your buffer. Look at how int 21h/0Ah works. Or WriteFile, or sys_write. They all demand that the caller specify a maximum number of bytes to accept. I'm sorry to be a "nut-case" about this, but it really annoys me that every time (unnamed company) releases a new version of their OS, new "exploits" are found. I suppose it would be high praise if "attackerz" went after your OS, but don't let 'em succeed! No "gets()"! Please!

A little-known(?) feature of Nasm is the ability to produce map files in "-f bin" mode. Normally, it's the linker that produces a map file, but since in "-f bin" mode, Nasm acts as its own linker (to the limited extent of putting ".data" after ".text", etc - there are othe options - RTFM), it can produce a map file. Normally, it's a command line option to the linker, but since it only applies to "-f bin", it has been made a directive. "" (anywhere in your source code) will cause Nasm to blab everything it knows about what went where into the named file. Can be useful solving problems if you and Nasm have different opinions about where things are supposed to be.

Oh yeah, I wanted to mention: if you want to have labels without colons, and not have Nasm complain about it, "-w-orphan-labels" will shut it up.

Just noticed this:


OEMLabel            db "LEAFOS"  ; Disk label - 8 chars


You probably want that padded (spaces or zeros... or?) so it really is 8 bytes...

Best,
Frank

Posted on 2010-05-28 20:02:16 by fbkotler