Viewing 8086 memory-areas A peek into the video display memory, the real-mode Interrupt Vector...

23
Viewing 8086 memory- areas A peek into the video display memory, the real-mode Interrupt Vector Table, and the ROM-BIOS DATA AREA
  • date post

    19-Dec-2015
  • Category

    Documents

  • view

    214
  • download

    0

Transcript of Viewing 8086 memory-areas A peek into the video display memory, the real-mode Interrupt Vector...

Viewing 8086 memory-areas

A peek into the video display memory, the real-mode Interrupt Vector Table,

and the ROM-BIOS DATA AREA

Hexadecimal displays

• The ability to exhibit computer-data in a form that’s understandable will be vital for exploring (and for debugging) our system

• The easiest scheme for doing it will be to show binary values in hexadecimal format

• Let’s look at a straightforward algorithm to convert any 16-bit number into a string of (four) hexadecimal numerals

Our ‘ax2hex’ procedure

• We create an array of the ascii-codes for the sixteen hexadecimal digit-characters

hex: .ascii “0123456789ABCDEF”

• Our procedure expects the binary value to be in register AX and the memory-address for the hex-string is in registers DS:DI

• Our procedure will preserve the contents of the CPU’s registers (no ‘side-effects’)

A 4-bit left-rotation

0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1

0 1 0 1 0 1 1 0 0 1 1 1 0 1 0 0

AX =

AX =

(Before rotation)

(After rotation)

Hi-nybble

Lo-nybble

A bitwise ‘AND’ opration

0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0BX =

? ? ? ? ? ? ? ? 0 1 1 1 0 1 0 0BX =

Lo-nybble

0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1$0xF =

(Before masking)

(After masking)

(bitmask-value)

& & & & & & & & & & & & & & & &

= = = = = = = = = = = = = = = =

Lo-nybble

BL is copied from ALUnknown bits in BH

Thus the lo-nybble (4-bits) gets ‘zero-extended’ to its equivalent 16-bit value

Array ‘lookup’ operation

‘0’ ‘1’ ‘2’ ‘3’ ‘4’ ‘5’ ‘6’ ‘7’ ‘8’ ‘9’ ‘A’ ‘B’ ‘C’ ‘D’ ‘E’ ‘F’hex:

0004BX =

hex( %bx ) = ‘4’

‘4’buf:

&bufDS:DI =

‘4’DL =

mov hex( %bx ), %dl

mov %dl, %ds:( %di )

So the number 4 in BX gets converted to the numeral ‘4’in the ‘buf’ array-cell at DS:DI

Algorithm implementation ax2hex: # converts the word-value in AX to a hex-string at DS:DI

pusha # save general registersmov $4, %cx # setup digit-count

nxnyb:rol $4, %ax # rotate hi-nybble into ALmov %al, %bl # copy the nybble into BLand $0xF, %bx # isolate the nybble’s bitsmov hex(%bx), %dl # lookup nybble’s ascii-codemov %dl, (%di) # store numeral into bufferinc %di # advance the buffer indexloop nxnyb # generate remaining digitspopa # restore saved registersret # return control to the caller

hex: .ascii “0123456789ABCDEF” # array of hex numerals

Algorithm applications

• We can use this binary-to-hex algorithm to view the contents of two memory-regions which ROM-BIOS startup-code initializes:– The table of ‘real-mode’ interrupt vectors– The values in the ROM-BIOS DATA-AREA

• Two ‘boot-sector’ demo-programs are named ‘viewivt.s’ and ‘viewrbda.s’

• They are on the CS 630 website:<http://cs.usfca.edu/~cruse/cs630>

Direct-Drawing to VRAM

• Both demo-programs perform their display by writing character-codes directly into the text-mode video-display memory-region (it starts at memory-address 0x000B8000)

• Each onscreen character is controlled by a pair of adjacent bytes in the video memory

Background color

Foreground color

ASCII character-code

Byte at odd-numbered offset Byte at even-numbered offset

Drawing ‘A’ in top-left corner

• Here’s a fragment of assembly-language code that draws an uppercase letter ‘A’ in the top-left corner of the screen (using the normal ‘white-on-black’ color-attributes):

mov $0xB800, %ax # address VRAM segmentmov %ax, %es # using the ES registerxor %di, %di # point ES:DI at top-left cellmovb $’A’, %es:0(%di) # draw character-code to VRAMmovb $0x07, %es:1(%di) # draw attribute-codes to VRAM

Organization of VRAM

• The first 80 byte-pairs in video memory (at offsets 0, 2, 4, …, 158) control the top row (row 0) on the screen (left-to-right order)

• Then the next 80 byte-pairs (offsets 160, 162, 164, …, 318) control the next row of text on the screen (i.e., row number 1)

• Altogether there are 25 rows of text, with 80 characters per row, when the display is programmed at startup for ‘standard’ text-mode

We need more rows for IVT

• The real-mode Interrupt Vector Table has room for 256 ‘pointers’ (each pointer being a doubleword segment-and-offset value)

• Not enough cells in the 80x25 text mode to view all 256 of the ‘vectors’ simultaneously

• We need 9 characters for each vector (i.e., 8 hex-digits, plus a space for separation), but 256 x 9 is greater than 80 x 25 =2000

Solution

• We can invoke a ROM-BIOS function that reprograms the display-hardware to show twice as many rows (in smaller-size text)

• Here’s a code-fragment to accomplish it:

mov $0x0003, %ax # set standard 80x25 textmodeint $0x10 # invoke BIOS video service

mov $0x1112, %ax # load 80x50 character-glyphsint $0x10 # invoke BIOS video service

Code ‘reuse’

• Our earlier ‘ax2hex’ procedure converts a word into a string of hexadecimal digits

• But each interrupt-vector is a doubleword!

• We could use a new procedure: ‘eax2hex’

• But it’s easier if we just call ‘ax2hex’ twice

• This requires us to clearly understand the Pentium’s scheme for addressing memory (i.e., the ‘little-endian’ storage convention)

‘Little endian’ versus ‘Big endian’

0x0369CF25EAX =

25CF6903

0123

0369CF25

0123

‘Little endian’ convention (least-significant byte is at lowest memory-address)

‘Big endian’ convention (most-significant byte is at lowest memory-address)

Intel x86 CPU’s use ‘little endian’ storage contention

Power-PC processor uses ‘big-endian’ convention

Example: convert vector 0 to hex

buf: .ascii “xxxxxxxx” # room for 8 hex-digits

Vector0:xor %bx, %bx # address bottom of memorymov %bx, %fs # using register-pair FS:BX

mov %fs:0(%bx), %ax # fetch vector’s low-wordlea buf+4, %di # point DS:DI to positioncall ax2hex # convert AX to hex-string

mov %fs:2(%bx)m %ax # fetch vector’s high-wordlea buf+0, %di # point DS:DI to positioncall ax2hex # convert AX to hex-string

# OK, ‘buf’ now holds the 8-digit hex-string representing vector 0

‘Real-Mode’ Memory Map

BOOT_LOCN0x00007C00

0x00007E00512 bytes

ROM-BIOS

VRAM

IVT

RAM

Vendor’s Firmware

Video Display Memory

No installed memory

Volatile Program Memory 1-MB

RBDA

0x000000000x000004000x00000500

1024 bytes256 bytes

Extended BIOS DataTop of RAM (= 0x000A0000)

Video-ROM

128 kbytes

64+ kbytes

Tool for exploring 8086 memory

• We have written a Linux device-driver, and a companion application-program, that lets you view the bottom megabyte of memory

• First you have to compile, and then install, the ‘8086.c’ device-driver kernel-object:

$ mmake 8086$ /sbin/insmod 8086.ko

• Then you can execute our ‘fileview’ tool: $ ./fileview /dev/8086

‘fileview’ commands

• You use arrow-keys to navigate memory, or <ENTER> to enter specific addresses

• You can adjust the hexadecimal formatting (‘B’ = byte, ‘W’ = word, ‘D’ = doubleword)

• You can quit by hitting the <ESCAPE>-key

Examples

• View ROM-BIOS code at 0xF0000• View Interrupt Vectors at 0x00000• View ROM-BIOS DATA at 0x00400• View Text-mode VRAM at 0xB8000• View Video ROM-BIOS at 0xC0000• View the BOOT_LOCN at 0x07C00• (Note: Linux may have ‘overwritten’ some

areas that ROM-BIOS startup-code set up)

Question

• The Extended BIOS Data Area resides in a portion of RAM that’s usually just below the VRAM memory-area (at 0x000A0000)

• This portion of RAM is subtracted from the total RAM available to operating systems

• So where’s the top of the ‘unused’ portion of the installed RAM?

BIOS ‘Get MemSize’ function

• There’s a function your real-mode code can call to find out where ‘top-of-ram’ is

• This function requires no arguments; it merely returns a value in the AX register

• That value gives the size of the memory (in kilobytes) that lies below ‘top-of-ram’

• You call this routine using: int $0x12

Our ‘memsize.s’ demo

• If you assemble, link, and install our demo, it will show you the size of ‘free’ memory when you reboot your workstation

$ cp /home/web/cruse/cs630/memsize.s .

$ as memsize.s –o memsize.o

$ ld memsize.o -T ldscript -o memsize.b

$ dd if=memsize.b of=/dev/sda4

Now boot from the GRUB ‘CS 630 partition’