Sunday, 16 April 2017

Concept of interrupt in Assembly language

What is interrupt? 
An interrupt interrupts the normal program flow, and transfers control from our program to Linux so that it will do a system call. Or in simple words,Interrupt is a mechanism by which a program’s flow control can be altered.You can think of it as like signaling Batman.You need something done, you send the signal, and then he comes to the rescue. You don’t care how he does his work.The most important thing to remember about an interrupt is that it can pause the execution of some program at any point between two instructions when an interrupt occurs.  Therefore, you typically have no guarantee that one instruction always executes immediately after another in the program because an interrupt could occur between the two instructions.If an interrupt occurs in the middle of the execution of some instruction, then the CPU finishes that instruction before transferring control to the appropriate interrupt service routine.

In DOS assembly, most things get done with the DOS services interrupt int 21h, and the BIOS service interrupts like int 10h and int 16h. In Linux, all these functions are handled by the kernel. Everything gets done with "kernel system calls", and you call the kernel with int 80h.

The BIOS library is divided into a bunch of sections called interrupts. Each interrupt handled a different aspect of the computer--keyboard I/O, screen drawing functions, file and disk I/O, and so on. Each interrupt then had a whole bunch of functions, each given a number. They used AH (and if the interrupt had a lot of functions, AX) to determine which function to call. Arguments to the interrupts were passed in registers instead of on the stack to speed things up a bit. 

                                      

            

Let's look at a simple interrupt call:
1. int 16h - BIOS Keyboard interrupt
        ah=0  reads key from keyboard without echo
                returns al=ascii, ah=scan code
        ah=1  finds out if a key was hit
              if no keys were pressed:
                zf set (ie, jz NoKey)
                ax=0
              if a key was pressed:
                zf clear (not set -> jnz KeyReady)
                ah=scan code
                 al=ascii

2.  int 21h - DOS functions
        ah=1  reads key from keyboard with echo
                returns al=ascii
        ah=2  prints a character (dl=ascii)
                returns nothing
        ah=5  prints character to printer (dl=ascii)
                returns nothing
        ah=9  prints a string ending in $ (ds:dx=pointer to string)
                returns nothing
        ah=a  buffered keyboard input (ds:dx=pointer to buffer)
              The buffer is in this form:
                1 byte   The max number of characters to read (including enter)
                1 byte   The number of characters read (it gets filled in)
                n bytes  The buffer (n must be at least 1)
              Enter (ascii 13: carriage return) is also stored.
        ah=4c Exit the program (al=error code)

3. int 10h - BIOS Video interrupt
        ah=0  set video mode (al=3 -> text,al=12h,13h -> vga)
                returns nothing
        ah=2  set cursor position (bh=0, dh=row, dl=column)
              dh and dl are zero-based
                returns nothing
       ah=c  display graphics pixel (al=color, bh=0, cx=column, dx=row)
              cx and dx are zero-based
                returns nothing

4. int 19h - Bootstrap loader: Will reboot your computer to the drive specified in dl.Some computers warm boot, some cold boot, and others do nothing register ah doesn't matter here.



Interrupt Instructions

Call to Interrupt Procedure (int, into)

int 3
int	imm8
into
Operation

interrupt 3 -- trap to debugger

interrupt numbered by immediate byte

interrupt 4 -- if overflow flag is 1

Description

The int instruction generates a software call to an interrupt handler. The imm8 (0 to 255) operand specifies an index number into the IDT (Interrupt Descriptor Table) of the interrupt routine to be called. In Protect Mode, the IDT consists of an array of 8-byte descriptors; the descriptor for the interrupt invoked must indicate an interrupt, trap, or task gate. In Real Address Mode, the IDT is an array of four byte-long pointers. In Protected and Real Address Modes, the base linear address of the IDT is defined by the contents of the IDTR.

The into form of the int instruction implies interrupt 4. The interrupt occurs only if the overflow flag is set.

The first 32 interrupts are reserved for system use. Some of these interrupts are used for internally generated exceptions.

The int imm8 form of the interrupt instruction behaves like a far call except that the flags register is pushed onto the stack before the return address. Interrupt procedures return via the iret instruction, which pops the flags and return address from the stack.

In Real Address Mode, the int imm8 pushes the flags, CS, and the return IP onto the stack, in that order, then jumps to the long pointer indexed by the interrupt number.

Example

Trap to debugger:

int $3

Trap to interrupt 0xff:

int $0xff

Trap to interrupt 4:

into

Interrupt Return (iret)

iret
Operation

return -> routine

Description

In Real Address Mode, iret pops CS, the flags register, and the instruction pointer from the stack and resumes the routine that was interrupted. In Protected Mode, the setting of the nested task flag (NT) determines the action of iret. The IOPL flag register bits are changed when CPL equals 0 and the new flag image is popped from the stack.

iret returns from an interrupt procedure without a task switch if NT equals 0. Returned code must be equally or less privileged than the interrupt routine as indicated CS selector RPL bits popped from the stack. If the returned code is less privileged, iretpops SS and the stack pointer from the stack.

iret reverses the operation of an INT or CALL that caused the task switch if NT equals 1.The task executing iret is updated and saved in its task segment. The code that follows iret is executed if the task is re-entered.


Operation

LDTR -> r/m[16]

Description

The Local Descriptor Table Register (LDTR) is stored by sldt as indicated by the effective address operand. LDTR is stored into the two-byte register or the memory location.

sldt is not used in application programs. It is used only in operating systems.

Example

Store the LDTR in the effective address (addressed by the EBX register plus and offset of 5):

sldt 5(%ebx)

Store Task Register (str)

str	r/m16

Operation

STR -> r/m(16

Description

The contents of the task register is stored by sldtas indicated by the effective address operand. STR is stored into the two-byte register or the memory location.

Example

Store str in the effective address (addressed by the EBX register plus an offset of 5):

str 5(%ebx)

Load Local Descriptor Table Register (lldt)

lldt    	r/m16
Operation

SELECTOR -> LDTR

Description

LDTR is loaded by LLDT. The operand (word) contains a selector to a local GDT (Global Descriptor Table). The descriptor registers are not affected.The task state segment LDT field does not change.

The LDTR is marked invalid if the selector operand is 0. A #GP fault is caused by all descriptor references (except LSL VERR, VERW, or LAR instructions).

LLDT is not used in application programs. It is used in operating systems.

Example

Load the LLDT register from the effective address (addressed by the EBX register plus and offset of 5):

lldt 5(%ebx)

Load Task Register (ltr)

ltr	r/m16
Operation

r/m16 -> Task Register

Description

The task register is loaded by LTR from the source register or memory location specified by the operand. The loaded task state segment is tagged busy. A task switch does not occur.

Example

Load the TASK register from the effective address (addressed by the EBX register plus and offset of 5):

ltr 5(%ebx)

Verify a Segment for Reading or Writing (verr, verw)

verr    	r/m16
verw    	r/m16
Operation

1 -> ZF (if segment can be read or written)

Description

VERR and VERW contains the value of a selector in the two-byte register or memory operand. VERR and VERW determine if the indicated segment can be reached in the current privilege level and whether it is readable (VERR) or writable (VERW). If the segment can be accessed, the zero flag (ZF) is set to 1, otherwise the zero flag is set to 0. For the zero flag to be set these conditions must be met:

  • The selector denotes a descriptor; the selector is "defined".

  • The selector is a code or data segment; not a task statement, LDT or a gate.

  • For VERR, the segment must be readable, for VERW, writable.

  • The descriptor privilege level (DPL) can be any value for VERR. otherwise the DPL must have the same or less privilege as the current level and the DPL of the selector.

Validation is performed as if the segment were loaded into DS, ES, FS, or GS and the indicated write or read performed. The validation results are indicated by the zero flag. The value of the selector cannot result in an exception.

Example

Determine if the segment indicated by the effective address (addressed by the EBX register plus an offset of 5) can be reached in the current privilege level and whether it is readable (VERR):

verr 5(%ebx)

Store Global/Interrupt Descriptor Table Register (sgdt, sidt)

sgdt    	mem48
sidt    	mem48
Operation

DTR -> mem48

Description

The contents of the descriptor table register is copied by sgdt/sidt to the six bytes of memory specified by the operand. The first word at the effective address is assigned the LIMIT field of the register. If the operand-size attribute is 32-bits:

  • The base field of the register is assigned to the next three bytes.

  • The fourth byte is written as zero.

  • The last byte is undefined.

If the operand-size attribute is 16-bits, the 32-bit BASEfield of the register is assigned to the next four bytes.

sgdt/sldt are not used in application programs, they are used in operating systems.

Example

Copy the contents of the Global Descriptor Table Register to the specified memory location:

sgdt 0x55555555

Copy the contents of the Interrupt Descriptor Table Register to the effective address (addressed by the EBX register plus an offset of 5):

sidt 5 (%ebx)

Load Global/Interrupt Descriptor Table (lgdt, lidt)

lgdt    	mem48
lidt    	mem48
Operation

MEM48 -> GDTR MEM48 -> IDTR

Description

The GDTR and IDTR are loaded with a linear base address and limit value from a six-byte operand in memory by the lgdt/lidt instructions. For a 16-bit operand:

  • Load the register with a 16-bit limit and a 24-bit base.

  • The six-byte data operand high-order eight bits are not used.

For a 32-bit operand:

  • Load the register with a 16-bit limit and a 32-bit base.

  • The six-byte data operand high-order eight bits are used as the high-order base address bits.

All 48-bits of the six-byte data operand are always stored into by the sgdt/sidt instructions. For a 16-bit and a 32-bit operand, the upper eight-bits are written with the high-order eight address bits. lgdt or lidt, when used with a 16-bit operand to load the register stored by sgdt or sidt, stores the upper eight-bits as zeros.

lgdt and lidt are not used in application programs; they are used in operation system. lgdtand lidt are the only instructions that load a linear address directly in 80386 Protected Mode.

Example

Load the Global/Interrupt Descriptor Table Register from memory address 0x55555555:

lgdt 0x55555555
lidt 0x55555555

Store Machine Status Word (smsw)

smsw    	r/m16

Operation

MSW -> r/m16

Description

The machine status word is stored by smsw in the two-byte register of memory location pointed to by the effective address operand.

80386 machines should use MOV ..., CR0.

Example

Store the machine status word in the effective address (addressed by the EBX register plus an offset of 5):

smsw 5(%ebx)

Load Machine Status Word (lmsw)

lmsw    	r/m16

Operation

r/m16 -> MSW

Description

The machine status word (part of CR0) is loaded by lmsw from the source operand. lmsw can be used to switch to Protected Mode if followed by an intersegment jump to clear the instruction queue. lmsw cannot switch back to Real Address Mode.

lmsw is not used in application programs. It is used in operating systems.

Example

Load the machine status word from the contents of the effective address (addressed by the EBX register plus an offset of 5):

lmsw 5(%ebx)

Load Access Rights (lar)

lar	r/m32, reg32

Operation

r/m16 (masked by FF00) -> r16

r/m32 (masked by 00FxFF00) -> r32

Description

If the selector is visible at the CPL (modified by the RPL) and is a valid descriptor type, lar stores a form of the second doubleword of the descriptor for the source selector. The designated register is loaded with the double-word (high-order) of the descriptor masked by 00FxFF00, and the zero flag is set to 1. The x in 00Fx ... indicates that these four bits loaded by lar are undefined. The zero flag is cleared if the selector is invisible or of the wrong type.

The 32-bit value is stored in the 32-bit destination register if the 32-bit operand size is specified. If the 16-bit operand size is specified, the lower 16-bits of this value are stored in the 16-bit destination register.

For lar, all data segment descriptors and code are valid.

Example

Load access rights from the contents of the effective address (addressed by the EBX register plus an offset of 5) into the EDX register:

lar 5(%ebx),  %edx

Load Segment Limit (lsl)

lsl	r/m32, reg32
Operation

Selector rm16 (byte) -> r16

Selector rm32 (byte) -> r32

Selector rm16 (page) -> r16

Selector rm32 (page) -> r32

Description

lsl loads a register with a segment limit (unscrambled). The descriptor type must be accepted by lsl, and the source selector must be visible at the CPL weakened by RPL. ZF is then set to 1. Otherwise, ZF is set to 0 and the destination register is unchanged.

The segment limit is loaded as a byte value. A page value limit in the descriptor is translated by lsl to a byte limit before lsl loads it in the destination register (the 20-bit limit from the descriptor is shifted left 12 and OR'd with 00000FFFH).

lsl stores the 32-bit granular limit in the 16-bit destination register.

For lsl, code and data segment descriptors are valid.

Example

Load a segment limit from the contents of the effective address (addressed by the EBX register plus an offset of 5) into the EDX register.

lsl 5(%ebx), %edx

Clear Task-Switched (clts)

clts
Operation

0 -> TS Flag in CR0

Description

The task-switched flag in register CR0 is cleared by clta. The TS Flag is set by the 80386 for each task switch. The TS Flag is used as follows:

  • If the TS Flag is set, each execution of the ESC instruction is trapped.

  • If the TS Flag and the MP Flag are both set, execution of a Wait instruction is trapped.

If a task switch is made after an ESC instruction is started, save the processor extension context before a new ESC instruction can be run. The fault handler resets the TS Flag and saves the context.

clts is not used in application program, it is used in operating systems.

clts can only be executed at privilege level 0.

Example

Clear the TS flag:

clts

Adjust RPL Field of Selector (arpl)

arpl	r16, r/m16

Operation

If RPL 1 < RPL 2, 1 -> ZF

Description

arpl has two operands. The first operand is a 16-bit word register or memory variable that contains the value of a selector. The second operand is a word register. If the RPL field of the second operand is greater than the RPL field of the first operand, ZF is set to 1 and the RPL field of the first operand is increased to match the RPL field of the second operand. Otherwise, no change is made to the first operand and the ZF is set to 0.

arpl is not used in application programs, it is used in operating systems.

arpl guarantees that a selector to a subroutine does not request a privilege greater than allowed. Normally, the second operand of arpl is a register that contains the CS selector value of the caller.

No comments:

Post a Comment