118 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
	
		
			4.1 KiB
		
	
	
	
		
			Groff
		
	
	
	
	
	
| .\" $Id$
 | |
| .TH I386_AS 6 "$Revision$"
 | |
| .ad
 | |
| .SH NAME
 | |
| i386_as \- assembler for Intel 80386
 | |
| .SH SYNOPSIS
 | |
| ~em/lib.bin/i386/as [options] argument ...
 | |
| .SH DESCRIPTION
 | |
| This assembler is made with the general framework
 | |
| described in \fIuni_ass\fP(6). It is an assembler generating relocatable
 | |
| object code in \fIack.out\fP(5) format.
 | |
| .SH SYNTAX
 | |
| .IP segments
 | |
| An address on the Intel 80386 consists of two pieces:
 | |
| a segment number and an offset.
 | |
| Usually, the segment number resides in a segment register, and
 | |
| assembly language addresses only give the offset, with the exception of
 | |
| the address of an inter-segment jump or call (see \fIaddressing modes\fP
 | |
| below).
 | |
| .IP registers
 | |
| The Intel 80386 has the following 32-bit registers:
 | |
| .br
 | |
| Four general registers: eax (accumulator), ebx (base), ecx (count), and edx (data).
 | |
| The low- and high order bytes of the low order words of these registers
 | |
| are separately addressable as ah, bh, ch, dh, and al, bl, cl, dl respectively.
 | |
| .br
 | |
| Two pointer registers: esp (stack pointer) and ebp (base pointer).
 | |
| .br
 | |
| Two index registers: esi (source index) and edi (destination index).
 | |
| .br
 | |
| Six segment registers: cs (code), ds (data), ss (stack), es (extra),
 | |
| fs (extra), and gs (extra).
 | |
| .IP "addressing modes"
 | |
| .nf
 | |
| .ta 8n 16n 24n 32n 40n 48n
 | |
| syntax		meaning
 | |
| 
 | |
| expr		the value of \fIexpr\fP is immediate data or
 | |
| 		an address offset. There is no special
 | |
| 		notation for immediate data.
 | |
| 
 | |
| register	one of the aforementioned general registers
 | |
| 		or their upper or lower halves, or one of the
 | |
| 		four segment registers.
 | |
| 
 | |
| (expr)		the value of expr is the address of the operand.
 | |
| 
 | |
| (reg)
 | |
| expr (reg)	the value of \fIexpr\fP (if present) + the contents of
 | |
| 		\fIreg\fP (which must be a pointer or an index register)
 | |
| 		is the address of the operand.
 | |
| 
 | |
| (reg1) (reg2)
 | |
| expr (reg1) (reg2)
 | |
| 		the value of \fIexpr\fP (if present) + the contents of
 | |
| 		\fIreg1\fP + the
 | |
| 		contents of \fIreg2\fP is the address of the operand.
 | |
| 
 | |
| (reg1) (reg2 * scale)
 | |
| expr (reg1) (reg2 * scale)
 | |
| 		the value of \fIexpr\fP (if present) + the contents of
 | |
| 		\fIreg1\fP + the
 | |
| 		contents of \fIreg2\fP multiplied by \fIscale\fP,
 | |
| 		is the address of the operand.
 | |
| 		\fIscale\fP can be either 1, 2, 4, or 8.
 | |
| 		This mode is only allowed for 32-bit addressing.
 | |
| 
 | |
| The next addressing mode is only allowed with the instructions
 | |
| "callf" or "jmpf".
 | |
| 
 | |
| expr : expr	the value of the first \fIexpr\fP is a segment number,
 | |
| 		the value of the second \fIexpr\fP is an address offset.
 | |
| 
 | |
| The following two addressing modes are only allowed with Intel 80[23]87 floating
 | |
| point processor instructions:
 | |
| 
 | |
| st
 | |
| st(num)		addresses the floating point processor stack. \fInum\fP
 | |
| 		must be between 0 and 7. st is the same as st(0).
 | |
| 
 | |
| .fi
 | |
| 
 | |
| .IP prefixes
 | |
| Each time an address is computed the processor decides which segment register
 | |
| to use. You can override the processor's choice by prefixing the instruction
 | |
| with one of eseg, cseg, sseg, dseg, fseg, or gseg; these prefixes indicate that the
 | |
| processor should choose es, cs, ss, ds, fs, or gs instead.
 | |
| .br
 | |
| Example: 
 | |
| .ti +8
 | |
| dseg movs
 | |
| .IP ""
 | |
| There is also an address size toggle, which switches between 32-bit and
 | |
| 16-bit address generation: a16 or a32. Normally, the assembler generates
 | |
| 32-bit addresses; both of these toggles make it generate 16-bit addresses
 | |
| for the next instruction, and also generate code to set the processor 
 | |
| temporarily in 16-bit address mode.
 | |
| .IP ""
 | |
| There is also an operand size toggle, which switches between 32-bit and
 | |
| 16-bit operands: o16 or o32. Normally, the assembler generates
 | |
| 32-bit operands; both of these toggles make it generate 16-bit operands
 | |
| for the next instruction, and also generate code to set the processor 
 | |
| temporarily in 16-bit operand mode.
 | |
| .IP ""
 | |
| Prefixes only affect the next instruction.
 | |
| .IP ""
 | |
| There are also the .use32 and .use16 assembler directives, which do not
 | |
| generate code, but change the assemblers default for operand and address sizes.
 | |
| Obviously, .use16 gives 16-bit modes, .use32 gives 32-bit modes.
 | |
| This is useful for assembling real mode 80386 code, or pure 16-bit
 | |
| modules (that do not have the D-bit set in the segment descriptor).
 | |
| These assembler directives stay in effect until there is another one.
 | |
| .SH "SEE ALSO"
 | |
| uni_ass(6),
 | |
| ack(1),
 | |
| ack.out(5),
 | |
| .br
 | |
| 80386 Programmer's Reference Manual, 1986, Intel Corporation
 |