Friday, February 4, 2011

选择子的赋值问题

书中对选择子的赋值语句为:


SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT



很奇怪的是:选择子一共16位,其中高十三位用来存放索引号,也就是描述符的偏移量,而低三位是用来存放别的信息的。



上述语句中是把偏移量放入低几位,这样的赋值没有错误,而且理应这样赋值。





解释如下:

这个问题要从三个方面考虑:

1. GDT表中的一项是8个字节,GDT表本身的大小可以有64K,即共有8K个表项

2.CS ES 等选择子只用高13位在GDT中定位数据,因此只能定位8K项,显然这个13位的数据不可能精确到字节,就是说不可能给出数据在GDT中以字节为单位的偏移,而只能给出以项(8字节)为单位的偏移.

3.用(LABEL_DESC_CODE32 - LABEL_GDT)得到的偏移是以字节为单位的(而且只要GDT表项正确,即每项确实占用了8个字节,则这个数据一定能被8整除),要放入CS中本来应该除以8,才是正确的.现在想想看除以8会是什么?对了,右移3位.但是你现在直接把它放入CS中,而CS的低3位用于TI和RPL,因此高13位中的值现在正是除了8的值.而低3位因为前面说了(LABEL_DESC_CODE32 - LABEL_GDT)一定能被8整除,所以低3位一定为0,这样一来,总是从GDT表中取数据,RPL总是为零,具有最高权限.

whats .org 100h?

ORG (abbr. for ORiGin) is an assembly directive (not an instruction). It defines where the machine code (translated assembly program) is to place in memory. As for ORG 100H this deals with 80x86 COM program format (COMMAND) which consist of only one segment of max. 64k bytes. 100H says that the machine code starts from address (offset) 100h in this segment, effective address is CS:100H. For com format the offset is always 100H. I suppose that addresses 0 to 100H could be used by bios, but I am not that sure. Another example is ORG 7C00H for intel exe program format.




Assembly Syntax:
%%% Example for small assembly program using org 100h


%%% mycom.asm

ORG 100h ; offset for com programs

mov ax, cs ; only one segment contains code+data

mov ds, ax ; data segemt address is equal to code segment adress

mov dx, hel ; Offset of hello world text

mov ah, 09h ; DOS function to output $-terminated string on screen

int 21h ; Call DOS to execute 09H

mov ax, 4C00h ; DOS function 4CH to finish this progam, return code 0

int 21h ; Call DOS

%%%

%%% here is good place for data

hel: db "Hello World$"; Text to output on screen

%%%

%%% translate this assembly program with NASM:

NASM mycom.asm -f bin -o mycom.com

Thursday, February 3, 2011

What does “int 0x80” mean in assembly code?

int means interrupt, and the number 0x80 is the interrupt number. An interrupt transfers the program flow to whomever is handling that interrupt, which is interrupt 0x80 in this case. In Linux, 0x80 interrupt handler is the kernel, and is used to make system calls to the kernel by other programs.




The kernel is notified about which system call the program wants to make, by examining the value in the register %eax (gas syntax, and EAX in Intel syntax). Each system call have different requirements about the use of the other registers. For example, a value of 1 in %eax means a system call of exit(), and the value in %ebx holds the value of the status code for exit().