1 / 25

Using data conversions

Using data conversions. How we can ‘peek’ at regions of system memory, such as the ROM-BIOS DATA AREA. Our programming tools. Last time we got some in-class practice at using our software development tools: The Linux assembler: as The Linux linker: ld The low-level copying utility: dd

colleena
Télécharger la présentation

Using data conversions

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Using data conversions How we can ‘peek’ at regions of system memory, such as the ROM-BIOS DATA AREA

  2. Our programming tools • Last time we got some in-class practice at using our software development tools: • The Linux assembler: as • The Linux linker: ld • The low-level copying utility: dd • The UNIX visual text-editor: vi • We applied these tools to the creation of a ‘boot-sector replacement’ (something we’ll need to know about for writing a mini OS)

  3. X86 ‘real-mode’ memory ROM-BIOS Expansion ROMs Video BIOS VRAM Extended BIOS Data Area DRAM EBDA 1-MB CS:IP BOOT_LOCN ROM-BIOS DATA AREA Interrupt Vector Table RBDA Disk Storage IVT

  4. Numerical conversions • While developing and debugging our own miniature operating system, we will often need to display some numerical values • The ROM-BIOS does not provide ‘helper’ functions for directly displaying raw data • But assembly language programmers learn to code efficient algorithms which perform frequently needed conversions

  5. Binary-to-Decimal • We can use a procedure that converts a value found in register AX into its representation as a string of decimal numerals, suitable for output to the terminal screen or to a printing device • It’s based on repeatedly dividing the AX value by ten (the radix of our decimal-system) to generate a stream of remainders, which are converted to ascii-codes and then displayed in reverse order

  6. Algorithm’s implementation ax2dec: # converts value in AX to a string of decimal digits at DS:DI pusha # save contents of registers mov $10, %bx # decimal-system base in BX xor %cx, %cx # initialize CX as digit-counter nxdiv: xor %dx, %dx # extend AX for next division div %bx # divide (DX,AX) by the base push %dx # save remainder on the stack inc %cx # and update our digit-counter or %ax, %ax # was the quotient nonzero? jnz nxdiv # yes, then do another division nxdgt: pop %dx # recover the newest remainder add $’0’, %dl # convert number to a numeral mov %dl, (%di) # store numeral in output-buffer inc %di # advance output-buffer index loop nxdgt # process all the remainders popa # restore contents of registers ret

  7. Left-versus-Right justification • The foregoing assembly language routine draws the string of decimal-digits using a “left-justified” display-convention: • But sometimes we prefer the appearance of a “right-justified” display-convention # left-justified # right-justified 34567 34567 963 963 2468 2468

  8. Our ‘memsize.s’ demo • We’ve written a boot-sector replacement program that reports the amount of real-mode memory available (in kilobytes) • It uses a ROM-BIOS function (int 0x12) to obtain this memory-size in the AX register • Then it uses repeated division by ten to convert the AX value into a right-justified string of decimal numerals for display

  9. Can avoid ‘interrupt-0x12’ • It’s possible for a program to find out the upper limit of real-mode memory without using the ‘int $0x12’ ROM-BIOS function • The memory-size is among the variables stored in the ROM-BIOS data-area – so we can fetch it directly if we know where it’s located, namely at address 0x00413 • ROM-BIOS is only useful in Real Mode

  10. Fetching value from 0x00413 .code16 # for execution in x86 ‘real-mode’ # # Here’s real-mode code that returns the ‘memsize’ value in register AX # get_memory_size: push %ds # preserve value in DS register mov $0x0040, %ax # address ROM-BIOS DATA-AREA mov $%ax, %ds # using the DS segment-register mov %ds:0x13, %ax # load the ‘memsize’ value into AX pop %ds # recover the former DS value ret # return control to the caller NOTE: The ‘int $0x12’ instruction can be stored in just two bytes: 0xCD, 0x12 (which is good to know if your program-code needs to fit within a small space)

  11. Binary-to-Hexadecimal • Our ability to see a computer’s binary-data in an understandable format will be vital in exploring hardware or debugging software • 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 numeral-characters

  12. Our ‘ax2hex’ procedure • We create an array of the ascii-codes for the sixteen hexadecimal digit-characters • 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’) hex: .ascii “0123456789ABCDEF”

  13. A 4-bit leftward-rotation Hi-nybble AX = 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 (Before rotation) AX = 0 1 0 1 0 1 1 0 0 1 1 1 0 1 0 0 (After rotation) Lo-nybble

  14. A bitwise ‘AND’ opration BL is copied from AL Unknown bits in BH Lo-nybble BX = ? ? ? ? ? ? ? ? 0 1 1 1 0 1 0 0 (Before masking) & & & & & & & & & & & & & & & & $0xF = 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 (bitmask-value) = = = = = = = = = = = = = = = = BX = 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 (After masking) Lo-nybble Thus the lo-nybble (4-bits) gets ‘zero-extended’ to its equivalent 16-bit value

  15. Array ‘lookup’ operation hex: ‘0’ ‘1’ ‘2’ ‘3’ ‘4’ ‘5’ ‘6’ ‘7’ ‘8’ ‘9’ ‘A’ ‘B’ ‘C’ ‘D’ ‘E’ ‘F’ hex( %bx ) = ‘4’ mov hex( %bx ), %dl BX = 0004 DL = ‘4’ DS:DI = &buf mov %dl, %ds:( %di ) buf: ‘4’ So the number 4 in BX gets converted to the numeral ‘4’ in the ‘buf’ array-cell at DS:DI

  16. Algorithm implementation ax2hex: # converts the word-value in AX to a hex-string at DS:DI pusha # save general registers mov $4, %cx # setup digit-count nxnyb: rol $4, %ax # rotate hi-nybble into AL mov %al, %bl # copy the nybble into BL and $0xF, %bx # isolate the nybble’s bits mov hex(%bx), %dl # lookup nybble’s ascii-code mov %dl, (%di) # store numeral into buffer inc %di # advance the buffer index loop nxnyb # generate remaining digits popa # restore saved registers ret # return control to the caller hex: .ascii “0123456789ABCDEF” # array of hex numerals

  17. Our ‘viewrbda.s’ demo • We can use this binary-to-hex algorithm to view the contents of regions in memory, such as the ROM-BIOS DATA-AREA • The RBDA includes a number of variables whose values change with system activity • For a dynamic view of this memory area, we need to draw and redraw its contents

  18. Direct-Drawing to VRAM • Our demo-program will perform its 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 Byte at odd-numbered offset Byte at even-numbered offset Background color Foreground color ASCII character-code

  19. 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 segment mov %ax, %es # using the ES register xor %di, %di # point ES:DI at top-left cell movb $’A’, %es:0(%di) # draw character-code to VRAM movb $0x07, %es:1(%di) # draw attribute-codes to VRAM

  20. Organization of VRAM • The first 80 byte-pairs within video memory (at offsets 0, 2, 4, …, 158) control the top row (row number 0) on the screen, in 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 first gets programmed at startup for ‘standard’ text-mode

  21. ‘Real-Mode’ Memory Map ROM-BIOS Vendor’s Firmware 64+ kbytes No installed memory Video-ROM Video Display Memory VRAM 128 kbytes Top of RAM (= 0x000A0000) Extended BIOS Data 1-MB Volatile Program Memory RAM 0x00007E00 BOOT_LOCN 512 bytes 0x00007C00 0x00000500 256 bytes RBDA 0x00000400 IVT 1024 bytes 0x00000000

  22. Several regions of interest • 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)

  23. In-class exercise #1 • Can you revise our ‘memsize.s’ program so that it would get its word-value directly from the ROM-BIOS DATA AREA, rather than by using an ‘int $0x12’ instruction?

  24. In-class exercise #2 • There is a ROM-BIOS service (int 0x11) which returns a word-value in register AX that is known as the ‘equipment_list’ flag • It’s a collection of bit-fields, rather than a single number, and gives us information about some of the hardware attached to the system (e.g., floppy drives, mouse) • Can you display it in hexadecimal format?

  25. The ‘Equipment-List’ flag 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 No of serial-ports (0..4) Modem installed (1=yes, 0=no) No of floppy drives (if bit 0 is set to 1) 00=one, 01=two, 10=three, 11= four Initial video display mode 00 = EGA/VGA 01 = color 40x25 10 = color 80x25 11 = mono 80x25 No of parallel-ports (0..3) Mouse port installed on system board (1=yes, 0=no) Math coprocessor installed (1=yes, 0=no) Bootable floppy-drive installed (1=yes, 0=no)

More Related