Having read the descriptor from the LDT, the CPU then has thebase address of the code segment.. 28 Windows Assembly Language & Systems ProgrammingThe CPU will only have to look in the sh
Trang 1WINDOWS ASSEMBLY LANGUAGE & SYSTEMS
PROGRAMMING
16- and 32-bit low-level programming
for the PC and Windows
Trang 20 Copyright 1997, Barry Kauler
All rights reserved No part of this publication may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Publisher.
In this book, many of the designations used by manufacturers and sellers to distinguish their products may be claimed as trademarks Due acknowledgement is hereby made of all legal protection Windows TM is a trademark of Microsoft Corporation.
Disclaimer Whilst due care has been taken in the preparation of this book, no responsibility is accepted for any inaccuracy, loss or damage to data, or consequential loss or damage The content of the Companion Disk is not guaranteed to be exactly as described.
This edition published by R&D Books / Miller Freeman
543 Richmond Street West Suite 223
Toronto, Ontario M5V lY6 Canada
Tel: (416) 504-3900 Fax: (4 16) 504-3902 Asia
Longman Singapore
25 First Lok Yang Road Singapore 2262
Tel: 65 268 2666 Fax: 65 268 7023
Editorial & Marketing Oftice R&D Books
1601 West 23rd Street, Suite 200 Lawrence, KS 66046
Tel: (913) 841-1631 Fax: (913) 841-2624 e-mail: orders@mfi.com Web: http://www.rdbooks.com
Trang 3Ch.
Preface
Page
xi
Preamble 1
Power-up the PC 2
The System Files 3
Number Systems 6
Registers and Memory 9
MemoryMapofthePC 12
The CPU & Support Chips 12
Conventional and Extended Memory 14
Segments 14
Real Mode 17
DOS Real Mode Programming 18
DOS Protected Mode Programming 18
Coding Restraints 20
Inside the 286/386l486/etc 2 1 CPU Registers 22
Instructions 23
Real and Protected Modes 25
Memory Management 25
Segmentation Only 25
Shadow Registers 26
Descriptors 28
386 Paging 28
Virtual-86 29
Contention Issues 3 1 Privileges 31
I/O Privilege 3 1 Task Switching 32
Interrupts 3 3 Real Mode Interrupts 33
Protected Mode Interrupts 34
Postamble 36
I
111
Trang 4Preamble 3 7
Stack Instructions 38
Transfer of Control 39
Conditional Jump 43
Addressing Modes 44
Segment Registers 46
String Instructions 47
Arithmetic Instructions 50
Logical Instructions 54
Code and Data Labels 56
Code Labels 56
Data Labels 58
Accessing Data 5 8 Pointers 59
LES, LDS, and LEA Instructions 60
Local Data 62
Type Override 63
Structures 65
Label Equates 66
Postamble 67
3 Opening Windows 69 Preamble 69
DOS versus Windows Programming 70
Internal Differences 7 1 Building a Windows Application 72
Library Functions 72
The Mechanics of Assembling and Linking 73
The Link Step 74
Two Steps for Resources 74
Windows Programming Mechanics 75
Objects 75
Handles 76
Instances 76
Messages 77
C Syntax 78
Message Loop 78
Callback Functions 79
Data Types 82
Trang 5Preamble 85
Getting Started 86
Tools Required 86
Source Files 89
Resource and Definition Files 89
Message Format 90
Make File 91
Development Cycle 92
Application Structure 94
Preliminary Code 94
Startup Code 96
WINMAIN{) 98
Callback Function 102
5 High-Level Assembly 109 Preamble 109
Include Files 109
Microsoft versus Borland 110
Skeleton Analysis 111
.MODEL Directive 119
Private and Global Data 120
MASM versus TASM Scope 121
TASM’s @@ 121
Life of Automatic Data 122
Assembling and Linking 123
MASM6 versus TASM 125
WINDOWS Qualifier 126
Prototypes 127
Callback Design 129
Other Incompatibilities 130
MASM Assembling and Linking 13 l MASM6 Program Listing 132
6 Program Design 137 Preamble 137
Object Addressing 138
Calling a Function 138
Early Binding 14 1 Late Binding 142
C++ Binding 142
Trang 6Assembly Language Binding 145
Use of THIS 145
Interfacing with C++ 147
Compiling to ASM O/P 147
In-Line Assembly 148
In-Line DOS and Don’ts 149
The ASM Stub 150
Compile and Assemble Steps 15 1 The Amazing 9-Line Program 153
A Skeleton Program 154
Overrides 156
Kickstart 157
Message Handling 157
The WINDOW Object 158
WINMAIN ) 162
Callback 165
MA=( ) 168
Inheritance 171
Getting it Together 175
Postamble 178
7 PC Hardware 179 Preamble 179
CPU bus 179
Control Bus 180
Address Decoder 182
I/OPorts 183
I/O Instructions 184
Keyboard Interface 184
AT-Class Keyboard Port Enhancements 186
PC Expansion Buses 187
Industry Standard Architecture (ISA) 188
Peripheral Connect Interface (PCI) 19 1 Postamble 194
8 BIOS, DOS, & Windows Low-Level Services 195 Preamble 195
BIOS and DOS Services 197
Standard DOS Interrupts 200
DOS Protected Mode Interface (DPMI) 203
INT-2Fh Extensions 205
Trang 7Ch.
9
10
11
Page
Windows Functions 207
Thunking 219
Generic Thunking 219
More Win95 “Improvements” 222
Device I/O Control 222
Dynamically Loadable Drivers 223
Threads 223
Memory Mapped Files 224
Postamble 224
Direct Hardware Access 225 Preamble 225
Initialisation 226
Addressing Segments 227
Direct Video 229
Restore Video 23 1 Change Video Mode 232
A Direct-Video Text-Mode Routine 232
Call REPAINTSCREEN 234
Ordinal Coordinates 235
To and From Text Mode 236
Video Output Issues 237
MessageInput 238
Experimenting 239
A Direct-Video Window Program 239
I/O Ports 244
Real-Time Events 249 Preamble 249
TSRs 250
Hooking a Vector 251
Service Routine (ISR) 253
Testing 255
Hardware Interrupts 256
XT Hardware Interrupts 256
AT Hardware Interrupts 257
Windows’ Standard Mode Hardware Interrupts 258
Interrupt Handler Code 260
Enhanced Mode Hardware Interrupts 263
Direct Memory Access 264
Trang 36A s s o c i a t i o n The next step in this saga is that the CPU can use the selector in
b e t w e e n the CS register to index into the current LDT and get the actual
d e s c r i p t o r address, or more correctly the descriptor, of the code segment.
ands/radow The IP register (or EIP) will have the offset into that segment from
r e g i s t e r which the CPU wiII fetch the instruction
Having read the descriptor from the LDT, the CPU then has thebase address of the code segment To avoid having to look in theLDT every time it wants to fetch the next instruction, the CPUmakes use of shadow registers again Every segment register has
an associated shadow register
Trang 3728 Windows Assembly Language & Systems Programming
The CPU will only have to look in the shadow register to find outthe starting address of the segment (plus some other information)and can then go ahead and put together the full 32-bit address forfetching the instruction
The CPU will add the base address to the offset IP and get a 32-bitaddress that can be put onto the address bus
Descriptors
I have introduced the descriptor as being an entry in the GDT orLDT There are various types of descriptors, but the mostcommon is the normal addressing type that we have beendiscussing so far
Each descriptor is 8 bytes in size, and Figure 1.13 shows what anormal descriptor looks like
Figure 1.13: Descriptor format.
I Size of Normally set “Base” is the address segment.
to zero on the of the segment.
286.
“Base+” extends the base segment addressing beyond
24 bits “#“extends the limit beyond 64K.
AC&?SS field The access byte in Figure 1.13 has various flags and codes It has
a two-bit DPL field (Descriptor Privilege Level) that determinesthe privilege level of the segment It has P (Present) and A(Accessed) bits that are used for moving the segments in and out
of memory There are R (Read) and W (Write) bits that setconstraints on reading and writing the segment There is also the
C (Conforming) bit and ED The latter is set if the segment is astack
I go into the description of the descriptor in far greater detail inChapter 12
386 Paging
There are two paging modes in the 386 One is built on top of thedescriptor tables, and the other, called virtual-86, does away withthe descriptor tables altogether
Trang 38Why go to this trouble? The operating system has trouble bringingsegments in and out of memory because they are all different sizes
- if a new segment is to be brought in, space must be found for it,but space released by a segment that has vacated its spot may not
be the right size This is a real problem for the operating system,and it ends up with lots of little unused gaps everywhere.Inefficiency
By transparently parcelling the segment up into lots of little pagesall the same size and storing them wherever there is a space, themismatch of segment sizes is no longer a problem We know that
a space vacated by a departing page will be exactly the right size
to take a new page No problem
Well, there is one To achieve this, more translation tables arerequired, called page tables The CR registers are used to address
these, and the page tables are kept in memory just like thedescriptor tables
The CPU has various extra registers for maintaining the pagingmechanisms, most importantly, CR3, which contains the base
address of the Page Table Directory.
Just for the record The address computed from the descriptor table, now renamed the
linear address (as it is no longer the final physical address), is
divided into fields, with bits 22 to 31 being an index into apage-table directory that gives the address of a particular pagetable Bits 12 to 21 are the index into this second table, whichcontains the final address Bits 0 to 11 are unchanged and becomepart of the final address
You will come across the words linear address later in the book Note that sometimes the words virtual address are used in various
books to mean the same thing, though there is a distinction Thelinear address is that 32-bit address that would be the physicaladdress if page tables didn’t get in the way
Virtual-86
This is another paging mechanism that does away with descriptortables It was intended to provide the 386 with better Protectedmode emulation of the 86 CPU than the 286 can manage, which itdoes very well
Trang 3930 Windows Assembly Language & Systems Programming
Although the 16-bit segment address is back, and once moreprograms designed to directly manipulate segment registers can do
so The CPU does compute a 20-bit address consisting ofparagraph address plus offset, but this is not put on the externaladdress bus Instead, it is processed via page tables, that is,translated to some other 32-bit address then put onto the addressbus
Once again, this paging is transparent to the programmer, but itdoes mean that the program, data, etc are not where you thinkthem to be judging from the segment registers
Virtual-86 mode is useful not just for emulating the old XTcomputer, but is the very foundation of Windows Enhanced mode
True, each virtual machine will have an addressing limit of lM,
but Windows can create many of these (Figure 1.14)
Figure 1.14: Virtual Real mode.
ent 1M address
Appar-i space.
1 Virtual XT PC
I Virtual XT PC
386 PC
Jbe upper8 Instead of putting the 20-bit linear address onto the address bus, as
bits of the for Real mode, virtual-86 mode uses the upper 8 bits of thislinear address as a lookup in the current page table - note that the tableaddress are entry contains the base address of the page, which is combinedremapped with the lower 12 bits of the linear address to form the actual32-bit address It is this final 32-bit address that the CPU puts out
for a memory access Refer also to page 274, Figure 11.2
Trang 40So what happens if your program writes directly to video RAM at
segment B800? This is up to the operating system, which mostlikely will create virtua1 screens for each task, setting them upanywhere it wants to in RAM
Contention Issues
There are various things to think about under this heading, but Ihave at this stage just addressed the issues of privileges, I/O, andtask switching
The topics are brought up at various points through the book, solook in the Index for other page references
Privileges
The dpl field in the descriptor defines the privilege level of that
segment Also you will see back on page 27, Figure 1.12, that theselector has a requested privilege level (rpl)
Because it is a 2-bit code, there are four possible levels, zero beingthe most privileged The kernel of the operating system willoperate up here (zero), while your lowly program will reside at alower privilege level.’
Your program’s level is basically reflected in what the rpl is set to,and this must be numerically equal to or less than the segment’sdpl to allow access to that segment - otherwise the CPU exits to
an error routine and the dreaded UAE (Unrecoverable ApplicationError) dialog box appears, and that’s the end of your program!
I/O Privilege
Privilege levels do have some impact on I/O If you look at theFLAGS register (see page 244), you’ll find 2 bits that hold the
Input/Output Privilege Level (IOPL) Your application must have
a privilege level numerically equal to or less than this to be able toperform I/O With Windows, the IOPL field is set to zero, mostprivileged
However, it is possible for the operating system to give permissionfor certain I/O to occur, even though the application doesn’t havethe right privilege I/O access involves use of the IN and OUTinstructions and control of the interrupt flag by CL1 and ST1
’ Windows 3.0 runs WinApps at level 1, DOSApps at level 3, and DLLs at level 1 Windows 3 I
and later run all three at level 3.
Trang 4132 Windows Assembly Language & Systems Programming
Windows error (exception) routine, which does have the privilege
to do what it wants - the routine allows CL1 and ST1 (clear or setinterrupt flag instructions) but does not let PUSHF or POPFinstructions affect the interrupt flag This is something to beaware of and a possible source of incompatibility with old DOScode It also means that an IRET from an interrupt routine maynot set the flag as it was prior to the interrupt
For more information on I/O, refer to page 244
Task Switching
Considering the complications of multitasking, I sometimeswonder if it is all worth it Perhaps a more effective solutionwould have been multiple CPU-boards, each single-tasking.Anyway, we are stuck with the current situation
Changing from one task (program) to another is a matter ofchanging to a new LDT,’ which involves the CPU looking into theGDT and getting the new LDT’s address
However, the “state” of the task about to be suspended must besaved, and the “state” of the incoming task must be restored Thisstate consists of the CPU and coprocessor registers plus variousmemory pointers and values, and an incredible time overhead isinvolved to save and restore this lot
The CPU has to maintain a special segment for each task, called
the Task State Segment (TSS), into which all of this goes Then, of
course, the CPU must keep track of where these TSSs are, so itmaintains descriptors for the TSSs in the GDT Thus the GDTcontains more than just descriptors for the LDTs
’ Windows 3.x and 95 have only one LDT for all applications, whether in Standard or Enhanced modes, which is a compromise in its design that can potentially cause trouble This limitation tallies with DPMI version 0.9, which in Windows maintains one LDT per virtual machine, not per task Windows is seen as a single client to DPMI Windows 95 32-bit applications have individual LDTs.