Author Topic: Doubts about some code  (Read 22956 times)

Offline rfpd

  • Jr. Member
  • *
  • Posts: 6
Doubts about some code
« on: January 08, 2014, 07:27:59 PM »
Quote
mov   di, input_buffer

mov   al, 0
mov   cx, 256
rep   stosb

mov   ax, input_buffer
mov   di, input_buffer

mov   ah, 10h
int   16h
stosb

mov   ah, 10h
int   16h
stosb

mov   ah, 10h
int   16h
stosb

mov   ax, 0
stosb

mov   si, input_buffer
call Print


input_buffer   times   256 db   0

It's not making sense to me why is input_buffer moved to di? and why in the beginning? it should be in the end and from di to the variable, why do we need cx? I didn't understand much, but I think it is a loop counter? Why can't stosb store all of those characters in one string. Why is the variable moved twice to di, why is it moved to ax, why is al set to 0? I searched a lot didn't find a thing except this code that came in a tutorial. About the code, it's for an os, it reads the keyboard input, 3 times, and then prints it all together. Print part is not there because I understand it, but this one confused me a lot. Thanks!

Oh and something else when do what is the real difference between "mov al, [example]" and "mov al, example". Imagine example has a 3 in it, first case will move 3 and the second will move example or will it attach al to example, so everytime al changes, example changes aswell? And why doesn't it work to use lodsb up there, stosb puts the input in di, the I did "mov si, di" and then lodsb. Thanks, again!
« Last Edit: January 08, 2014, 07:30:57 PM by rfpd »

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Doubts about some code
« Reply #1 on: January 08, 2014, 08:31:07 PM »
Knowing instructions such as stosb is not enough. You need to know about the instruction setup when using such instruction.

STOSB instruction setup:

1. AL/AX/EAX as source
2. ES as the segment of the destination
3. DI point to the destination data (so you need ES:DI setup prior to using STOSB)
4. Repetitions in CX/ECX (you guessed correct)
5. Direction flags forward or reverse

You need to know this kind of thing when attempting to use any instruction. RTFM.

Transfer instruction:

1. mov al,byte[example]  --> transfers a byte to AL from memory address of [example]
2. mov al, example --> doesn't make sense. It should be mov ax,example. Transfers the address of example to AX.

Start small with simpler examples.

Offline rfpd

  • Jr. Member
  • *
  • Posts: 6
Re: Doubts about some code
« Reply #2 on: January 08, 2014, 10:55:21 PM »
Thanks for the answer :D. When an address is moved to ax will it be attached to it? I mean if I change ax will the address change aswell?

Offline rfpd

  • Jr. Member
  • *
  • Posts: 6
Re: Doubts about some code
« Reply #3 on: January 08, 2014, 11:33:48 PM »
What do you mean by ES and ES:DI, I googled everywhere but I didn't understand the meaning. Why can't we just fetch from di, is it stored in es? Or es is used to find di? Thanks.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Doubts about some code
« Reply #4 on: January 09, 2014, 12:34:33 AM »
No. (if I understand the question) ax will change, but the address of "input_buffer" (or whatever) will not

Code: [Select]
; move address of input_buffer to di - "stosb" is going to use it
mov   di, input_buffer


; clear out buffer - this is probably not necessary
mov   al, 0
mov   cx, 256
rep   stosb
; "stosb" is equivalent to
; mov [es:di], al
; inc di
; with "rep", it does it cx times

mov   ax, input_buffer ; useless, as far as I can see
mov   di, input_buffer  ; since di has changed, we need to reload it

; get one character
mov   ah, 10h
int   16h
; put it in our buffer at [es:di], advancing di for the next one
stosb

; again
mov   ah, 10h
int   16h
stosb

; and again
mov   ah, 10h
int   16h
stosb


; since we have filled the buffer with zeros,
; our string should already be zero-terminated
; I guess this makes sure.
; only al is used, zeroing ax is overkill but does no harm
mov   ax, 0
stosb

; presumably "Print" uses this
mov   si, input_buffer
call Print


input_buffer   times   256 db   0

Next question: "es" is a segment register. In real mode addressing, an address is formed by a segment multiplied by 16, plus the offset (this changes in protected mode!). The usual default segment register is "ds". That is, if we did:
Code: [Select]
mov al, [di]
it would be equivalent to:
Code: [Select]
mov al, [ds:di]
We don't need to write the "ds" and usually don't want to. There are exceptions, for example "[bp]" defaults to "[ss:bp]". The reason we're using "es" here is NOT because we're using "[di]" but because we're using the "string instructions" - lodsb, stosb, movsb, scasb, cmpsb, insb, outsb - I may have missed some, and there are "word" and "dword" versions - and I guess "qword" versions, these days. The destination for these (those that have a destination) uses "es" as the segment register.

Presumably, earlier code has set "es" (and "ds" and "ss") where they need to be, and taken care of the other considerations dreamCoder has mentioned. Sometimes people ASSume things they shouldn't. Just because you find something on the internet - even if it claims to be a "tutorial" - doesn't necessarily mean it's right!

Googling for "real mode addressing" might turn up some more useful links. Or ask again here, if you don't understand something.

Best,
Frank



Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Doubts about some code
« Reply #5 on: January 09, 2014, 07:50:16 AM »
Thanks for the answer :D. When an address is moved to ax will it be attached to it? I mean if I change ax will the address change aswell?

Just like Frank said. The answer is no. If you change AX, you destroy the current value of AX for good. The address of example is still intact. What you did in your code seemed to demonstrate this.

Code: [Select]
mov ax, input_buffer ; address of input_buffer in AX
...
mov ah,10h  ;now you destroy it

Take it slowly. Don't rush.




Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Doubts about some code
« Reply #6 on: January 09, 2014, 08:00:58 AM »
What do you mean by ES and ES:DI, I googled everywhere but I didn't understand the meaning. Why can't we just fetch from di, is it stored in es? Or es is used to find di? Thanks.

ES is the segment register, holding the address of a segment (a segment is a memory block, just like a building). Your data (your room in that building) may reside in that segment somewhere and in the case of STOSB setup, the destination data must reside in that segment (where the address of that segment is currently in ES register). The address of the destination data inside the segment must be pointed to by the DI register. So now you have the complete ES:DI address for your input_buffer, as expected by STOSB instruction.

Your confusion revolves around the difference between extra segment and the Extra Segment (ES) register. Don't get them mixed up.

Offline rfpd

  • Jr. Member
  • *
  • Posts: 6
Re: Doubts about some code
« Reply #7 on: January 09, 2014, 01:42:45 PM »
Code: [Select]
mov   di, input_bufferor
Code: [Select]
mov   si, input_buffer
So this is like saying, si and di ask for an address, we give them and then they use that address to store, load data? Like a configuration?

The es:di is like we have an hotel (es) and there we have a person called di, that we must find. So we need to say es:di, like di in es hotel, right? If we only type di it will have no place to look? Is that right?

Code: [Select]
input_buffer   times   256 db   0
Does this means that we can only store one time in a variable? By that logic we do times 256 to store in that variable 256 characters, right?

Thanks for the help, sorry for asking so many questions but I don't understand what I read in the internet.

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Doubts about some code
« Reply #8 on: January 09, 2014, 06:59:48 PM »
All your assumptions and analogies are quite correct in the case of 16-bit real mode segmentation. Almost every data / instructions in 16-bit real mode has their address in segment:offset format, like CS:IP, DS:DX, ES:DI,SS:BP, DS:yourdata etc etc. DS is the default segment for all data, thus many programmers skip it when addressing their data in memory. So you may not always see them in their full segment:offset format. When an instruction or you change the segment for data to other than the default (DS), you are said to be using segment override. So STOSB is one example of segment override (using ES instead of the default DS for keeping data).

Instructions have unique setup in regards to memory and registers, including STOSB that requires the destination (the place where you'll actually STORE BYTE of your string) to be addressed by ES:DI. So in short, ES (memory) is the building, then the DI will point to the starting address of the particular data (input_buffer) in that segment pointed to by ES (register). Remember, a memory block (segment) becomes an extra segment only when its address is kept in the ES register. Similarly, a random block of memory would only become a data segment only if you place its address into the DS register.

Another example is the famous int 21h, function ah=9 to print a string. This is a good example of segment:offset notation. This interrupt also has its own instruction/interrupt setup.

Instruction Setup for INT 21h to print a null-terminated string:

1. AH = 9h
2. The string offset/address must reside in DX
3. The Segment must be in DS
4. The string must be null-terminated ('$')

The decision on the segment location is application-dependent.  In your code, try to find how the author/tutorial setup the ES.

So the keywords here are : segment:offset, instruction setup.

« Last Edit: January 09, 2014, 07:08:14 PM by dreamCoder »

Offline rfpd

  • Jr. Member
  • *
  • Posts: 6
Re: Doubts about some code
« Reply #9 on: January 11, 2014, 06:24:54 PM »
Thanks, but now I have a new problem my boot file reached maximum space. What should I do?

Quote
Bits   16
jmp   Main

Print:
lodsb
cmp   al,0
je   Done
mov   ah, 0eh
int   10h
jmp   Print
ret

Done:
ret

Input:
call cposition
mov   di, input_buffer
mov   cx, 256
rep   stosb
mov   di, input_buffer
call Prompt
ret

Prompt:
mov   ah, 10h
int   16h
stosb
mov ah, 0eh
int 10h
cmp al, 13
je Compare
jmp Prompt
ret

Compare:
mov si, input_buffer
lodsb
mov ah, [help]
cmp al, ah
je helpb
jmp notrec
ret

cposition:
mov ah, 03h
int 10h

mov ah, dh
inc ah
mov dh, ah

mov ah, 02h
mov dl, 0
int 10h
ret

notrec:
call cposition
mov si,notrecz
call Print
jmp Input
ret

helpb:
call cposition
mov si, helpa
call Print
jmp Input
ret

Main:
cli
mov ax, 0x0000
mov ss, ax
mov sp, 0xFFFF
sti

mov ax, 07C0h
mov ds, ax
mov es, ax

mov [bootdrive], dl

mov   si,msg
call Print

mov ah, 02h
mov dh, 1
mov dl, 0
int 10h

jmp Input
cli
hlt

bootdrive db 0
helpa db "You called for help, no help to give",0
msg   db   "Rui OS type help for aditional information", 0
help db  "help",0
notrecz db "Command not recognized",0
input_buffer   times   256 db   0

times 510 - ($-$$)   db   0

dw   0xAA55

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Doubts about some code
« Reply #10 on: January 11, 2014, 06:31:52 PM »
Thanks, but now I have a new problem my boot file reached maximum space. What should I do?

Hi!

Next code file you have to load from disk.

EDIT0:

You might be interested into bios interrupt 13h - Low Level Disk Services.
Find more information about on BIOS interrupt call wikipedia.

« Last Edit: January 11, 2014, 06:35:13 PM by encryptor256 »
Encryptor256's Investigation \ Research Department.

Offline rfpd

  • Jr. Member
  • *
  • Posts: 6
Re: Doubts about some code
« Reply #11 on: January 11, 2014, 10:45:34 PM »
Yes I already saw it, but I didn't find a site that explained it properly. Thanks I will check this out!

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Doubts about some code
« Reply #12 on: January 12, 2014, 08:37:27 AM »
Yes I already saw it, but I didn't find a site that explained it properly. Thanks I will check this out!

Here is my source code of bootloader,
that loads next code from floppy drive i think,
and then executes that loaded code.

Here i read that code (load into fixed address 0X007E:0X0000):
Code: [Select]
        .........................
        ; Read segment
MOV AX,0X007E
MOV ES,AX
MOV BX,0X0000

MOV AH,0X02
MOV AL,1
MOV CH,0
MOV CL,2
MOV DH,0
MOV DL,BYTE [cdDrive]
INT 0X13
JC .ABORT
        .........................

Here, later, i jump on it (0X007E:0X0000):
Code: [Select]
        .........................
CLI
JMP 0X007E:0X0000

Notes:
  • If still interested, then see attachment, "bootloader.asm".
  • Bootloader worked when i tested it, some time ago.
  • Next sector must be written to floppy drive first sector, i think.

You should know this site: OsDev.Org, site, is about os development.
Some links from that site, that i liked:

Here is one more site named: MikeOs
Some links from that site, that i liked:
How to write a simple operating system
There is a section: "Going further", so, that is what you are doing now.

Encryptor256's Investigation \ Research Department.

Offline dreamCoder

  • Full Member
  • **
  • Posts: 107
Re: Doubts about some code
« Reply #13 on: February 08, 2014, 02:34:33 AM »
Thanks, but now I have a new problem my boot file reached maximum space. What should I do?

Quote
Bits   16
jmp   Main

Print:
lodsb
cmp   al,0
je   Done
mov   ah, 0eh
int   10h
jmp   Print
ret

Done:
ret

Input:
call cposition
mov   di, input_buffer
mov   cx, 256
rep   stosb
mov   di, input_buffer
call Prompt
ret

Prompt:
mov   ah, 10h
int   16h
stosb
mov ah, 0eh
int 10h
cmp al, 13
je Compare
jmp Prompt
ret

Compare:
mov si, input_buffer
lodsb
mov ah, [help]
cmp al, ah
je helpb
jmp notrec
ret

cposition:
mov ah, 03h
int 10h

mov ah, dh
inc ah
mov dh, ah

mov ah, 02h
mov dl, 0
int 10h
ret

notrec:
call cposition
mov si,notrecz
call Print
jmp Input
ret

helpb:
call cposition
mov si, helpa
call Print
jmp Input
ret

Main:
cli
mov ax, 0x0000
mov ss, ax
mov sp, 0xFFFF
sti

mov ax, 07C0h
mov ds, ax
mov es, ax

mov [bootdrive], dl

mov   si,msg
call Print

mov ah, 02h
mov dh, 1
mov dl, 0
int 10h

jmp Input
cli
hlt

bootdrive db 0
helpa db "You called for help, no help to give",0
msg   db   "Rui OS type help for aditional information", 0
help db  "help",0
notrecz db "Command not recognized",0
input_buffer   times   256 db   0

times 510 - ($-$$)   db   0

dw   0xAA55

Jeez, u have no idea how to setup ES but you are writing a bootloader already? God help us all.