Guidance with 16bit MASM in directly write to video RAM using int 21h

Started by Shayaan_Mustafa, June 08, 2014, 01:48:13 AM

Previous topic - Next topic

Gunther

Quote from: Shayaan_Mustafa on June 10, 2014, 01:43:52 AM
Because mostly we use these statements;
mov ax, @data
mov ds, ax
mov dx, offset msg

But this time we used si. Can't we use dx again?
No, not with

       movsw

You can check this with the source which Wannabe provided. Thank you Wannabe.  :t It's very instructive for beginners.

Gunther
You have to know the facts before you can distort them.

Shayaan_Mustafa

Yes, I see Wannabe's link.
Here I have something to ask which I never get to understand. Actually what does this mean DS:[SI] or ES:[DI]? How would you define these two? What are these telling to us?

Gunther

Mustafa,

a DOS real mode address is a logical address: SEGMENT:OFFSET. Both are 16 bit wide. The segment address is in a segment register, which can be CS, SS, DS, ES, FS, GS. You have no access to CS and that is reasonable. You can change SS, but your stack would break down if you do so.
You can access all the other segment registers. The linear or physical RAM real mode address is calculated segment*16 + offset, resulting in a 20-bit address in the range of 00000h to FFFFFh. So DS:[SI] points to one logical address, ES:[DI] points to another and ES:[BX] points to third address. What's the problem? The MOVSW statement is connected with DS:[SI] as pointer to the source and ES:[DI] as pointer to the destination. That's hard wired by Intel engineers and no one can change that. But you should know it.

Gunther
You have to know the facts before you can distort them.

Shayaan_Mustafa

I have attached a picture. See it. I have few questions regarding it.

My programming is mostly related to the 16-bit. So I am focusing on the Table 2-3 as in the figure.

Here are my questions:
1) How do we know when to use SS:[SP] or SS:[BP]? Or we can use both anywhere or their functions are specified separately?
2) How do we know when to use DS:[BX] or DS:[DI] or DS:[SI]? Or we can use them anywhere we want? And What is meant by the sentence "an 8- or 16-bit number"?
3) What is the meaning of this line "ES      DI for string instructions        String destination address"? Is this only for string? Can we not use ES:[DI] for any other purpose?
4) Final. DI is the offset for both ES and DS in the 4th and 3rd lines respectively of the table 2-3. If we use DS:[DI] then we can't use ES:[DI], am I right or wrong?

dedndave

those are some very rudimentary questions
you should probably do a little reading before going too much farther   :t

i suggest you start with chapter 1

https://courses.engr.illinois.edu/ece390/books/artofasm/artofasm.html

dedndave

the register names have some meaning, actually

CS = code segment
DS = data segment
ES = extra segment
SS = stack segment

AX = accumulator
BX = base (address)
CX = count
DX = data

SI = source index
DI = destination index

SP = stack pointer
BP = base pointer (stack frame base)

there are also Flags register and IP (instruction pointer)

dedndave

many of the registers may be used for multiple purposes
however, CS:IP is always used to point to the next instruction to be executed
and SS:SP always points to the current "top of stack" (which is numerically the bottom of the stack)

Shayaan_Mustafa

Quotethose are some very rudimentary questions
you should probably do a little reading before going too much farther   :t

i suggest you start with chapter 1

https://courses.engr.illinois.edu/ece390/books/artofasm/artofasm.html
I have something to say sir. You will be thinking that I am a blank person in the assembly language. But this is not the case. I know its basics and advance too. I also know how to turn on and off capslock, numlock, etc via assembly language.
Now obviously your question should be then why I ask about basics of the assembly language as in the above quote. Because in talking with expert even about basics, sometimes give rise to those discussions which we don't think and don't found in the book.

Quotethe register names have some meaning, actually

CS = code segment
DS = data segment
ES = extra segment
SS = stack segment

AX = accumulator
BX = base (address)
CX = count
DX = data

SI = source index
DI = destination index

SP = stack pointer
BP = base pointer (stack frame base)

there are also Flags register and IP (instruction pointer)
I know all these abbreviations sir.

Quotemany of the registers may be used for multiple purposes
however, CS:IP is always used to point to the next instruction to be executed
and SS:SP always points to the current "top of stack" (which is numerically the bottom of the stack)
I know this too :-)

I have some questions related with MASM debugger.
I want to know how to use code view? Because our teacher didn't used it.
Here is the picture of the codeview

Shayaan_Mustafa

This is my program

.model small
.stack 32h

.data
msg Db 'MESSAGE'

.code
mov ax,@data
mov ds,ax
mov SI, offset msg
mov ax,0B800H
mov es,ax
mov DI,1920
mov cx,7
mov ah,14
Again:
        LODSB
        STOSW
loop Again
mov ah,4ch
int 21h
end

I run this program and view it in codeview but where is my message located in the memory? How to see it?
Here is picture of this program in the codeview sir.

dedndave

i never got around to using CodeView
i used SymDeb, which is very similar to Debug
so i am not sure about CodeView commands

in SymDeb, you can type ? and press enter to get a list of available commands
the "d" command may be used to dump memory
and, it may be modified to dump bytes, words, dwords, etc
db dump bytes
dw dump words
dd dump dwords
the d command may be further modified with a start address or a range of addresses
d 3E52:0
d 100 200

notice that your code segment is 3E51 and the data segment is 3E52
you can use this command to see the string
db 3e52:0

it will dump bytes, starting at 3e52:0
your string is at 3e52:e

the segments are relocatable, and may be different each time you run CodeView

dedndave

QuoteHere are my questions:
1) How do we know when to use SS:[SP] or SS:[BP]? Or we can use both anywhere or their functions are specified separately?
2) How do we know when to use DS:[BX] or DS:[DI] or DS:[SI]? Or we can use them anywhere we want? And What is meant by the sentence "an 8- or 16-bit number"?
3) What is the meaning of this line "ES      DI for string instructions        String destination address"? Is this only for string? Can we not use ES:[DI] for any other purpose?
4) Final. DI is the offset for both ES and DS in the 4th and 3rd lines respectively of the table 2-3. If we use DS:[DI] then we can't use ES:[DI], am I right or wrong?

1)
SP is the stack pointer
when you PUSH or POP, you can watch it change
sometimes, we add or subtract on the SP register, to reserve space for several and/or larger data items

BP is typically used as a stack frame base pointer
like the SP register, it also references the SS segment
however, the BP register does not change when you PUSH or POP

you will see more use of the EBP register in 32-bit code where function arguments are passed on the stack
in 16-bit code, arguments were often passed in registers
compiled code may have passed arguments on the stack
but, unless you are disassembling compiled code, you rarely saw it used that way
however, BP is still used for local data

there are many forum posts to search on this subject

2a)
for BX, SI, or DI, the default reference segment is DS
however, when using string instructions, ES is the default reference segment for DI
this allows moves and compares across segment boundries

2b)
not really sure why they mentioned 8-bit values - it's a little confusing for learning readers
but, an address offset does not need to be greater than 255   :biggrin:

3)
see answer 2a
also, you are looking at the default reference segments
you may override them by specifying a different segment
SS:[DI], ES:[DI], even CS:[DI] are allowed
for BP, the default is SS, but may also be overridden to DS:[BP] (or any other segment)

4)
sometimes, DS and ES may have the same value
the question depends on context - that's why i suggested more reading

dedndave

i should mention something, so you don't waste a lot of time.....

if your instructor is using 16-bit code, then learn what you must to pass the class
but, 16-bit code is considered obsolete
it won't even run under newer 64-bit OS's
don't spend too much time on it, beyond what's required for class

writing code for 32-bit or 64-bit windows is very different from 16-bit DOS code
in fact, those who have written 16-bit code have a harder time learning it, in some respects
because they have to "un-learn" all the 16-bit segmentation stuff

MichaelW

Quote from: Shayaan_Mustafa on June 10, 2014, 08:36:19 PM
I run this program and view it in codeview but where is my message located in the memory? How to see it?

If you know where in the data segment it is (for your example code it should be at offset 0), after you load the EXE into CV, trace through the code until you have executed the instructions that initialize DS, then at the prompt (">") enter:

d ds:0
Well Microsoft, here's another nice mess you've gotten us into.

BlueMR2

Quote from: dedndave on June 08, 2014, 01:48:58 PM
i remember   :lol:

we used to jump through all sorts of hoops to squeeze the smallest improvement out of the machine
the V20 processor was about 12% faster than an 8086 with the same clock

i had a Juko motherboard that had a 10 MHz V20 (i even bought a 10 MHz 8087)
it boasted 1 Mb of RAM - you could page flip part of it
i also had a 2 Mb LIM memory board
i wrote a specialized device driver that treated the combined extra RAM as a single RAMDRIVE
at boot-time, i copied the most common external DOS commands and my favorite EXE's into the RAMDRIVE

I'm doing more than remembering.  I just dug out my old 8088 machine the other day...  10mhz.  Never was able to find an 8087 for it (will accept one if somebody has one to give away!).  768 KiB of RAM, 640 maps the normal way.  The last 128 can be used as a ramdisk with a special driver (no idea where it maps, I've scanned upper memory ranges and never found a read write window that corresponds to it).  Currently has a 1 MiB 16-bit VGA card stuffed into (actually, hanging over the edge of) an 8-bit slot.  Works fine though.  :-)
My Code Site
https://github.com/BrianKnoblauch

Gunther

Quote from: BlueMR2 on June 14, 2014, 12:08:33 AM
I'm doing more than remembering.  I just dug out my old 8088 machine the other day...  10mhz.  Never was able to find an 8087 for it (will accept one if somebody has one to give away!).  768 KiB of RAM, 640 maps the normal way.  The last 128 can be used as a ramdisk with a special driver (no idea where it maps, I've scanned upper memory ranges and never found a read write window that corresponds to it).  Currently has a 1 MiB 16-bit VGA card stuffed into (actually, hanging over the edge of) an 8-bit slot.  Works fine though.  :-)

So you can do some retro programming.

Gunther
You have to know the facts before you can distort them.