1.sizeof,以字节为单位的长度
lengthof,其中的项数,并且参数必须是变量,不能是“关键字,变量类型”
2.局部变量时用ebp来做指针操作。全局变量用offset.
3.lea传送的地址,参数中可以做算术运算,简单的等同于move,如果比较复杂用mov就多步才能实现,lea一步实现
mov传送的是内容
4.如果要在invoke伪指令的参数中用到局部变量的地址,用addr(用eax实现,并且只能用在invoke中),并且左边的参数不能有eax
5.80386的通用寄存器都是32位的,段寄存器都是16位的。
所以,80386可以用任何一个通用寄存器来间接寻址,不必分段就可以访问所有的内存地址。
此时,需要64位长的数据来表示段的属性,记段描述符(Segment Descriptor),这就是段寄存器发挥作用的地方了。
由于段寄存器是16位的,无法放下64位的段描述符,解决方法是把所有的段描述符顺序放到内存中的指定位置,组成一个
段描述表(Descriptor Table),而段寄存器中的16位用来做索引信息,指定某一段的属性用段描述符表中的第几个描述符来表示。
这样,段寄存器中的信息不再是段地址,二是段选择器(Segment Selector)
段描述符表的位置,64位的GDTR,16位的LDTR
GDTR:全局描述符表,通常包含操作系统所使用的代码段,数据段和堆栈段的描述符及各任务的LDT段等,只有一个。
LDTR:每个任务都有一个独立的LDT,包含有每个任务私有的代码段,数据段和堆栈段的描述符。也包含改任务所使用的一些门描述符,如任务门和调用门。
不同任务的局部描述符表分别组成不同的内存段,描述这些内存段的描述符当做系统描述符表存放在全局描述符表中,和GDTR直接指向内存地址不同,LDTR和CS,DS等段选择器一样只存放索引值,指向局部描述符表内存段对应的描述符在全局描述符表中的位置。这样切换任务时只需切换LDTR,系统当前的局部描述符表LDT也随之切换,便于各任务直接数据的隔离,但GDT并不随着任务的切换而切换。
6.80386中,除了和CR3寄存器(指定当前页目录的地址)相关的指令使用的是物理地址外,其他所有指令都是用的线性地址寻址。
是否启用内存分页机制是由80386处理新增的CR0寄存器中的位31(PG位)决定的,如果PG=0,分页机制不可用,即所有指令寻址的地址都是系统中的实际物理地址,PG=1时,80386处理器进入内存分页管理模式,所有的线性地址要经过页表的映射才得到最后的物理地址。
页表规定的不仅是地址的映射,同时还规定了页的方位属性,如是否可读,可写,可执行等。
在程序开始时,CS,DS,ES,SS都已经指向了正确的描述符,整个程序的声明周期内,程序员不必改动这些寄存器,也不必关心他们的值究竟是多少,所以在Win32汇编代码中不是用不到段寄存器,二是用户不必关心段寄存器。
7.为了是高优先级的代码能够安全的被优先级低的代码调用,保护模式下增加了“门”的概念,“门”指向某个优先级高的程序所规定的入口点,所有优先级低的程序调用优先级高的程序只能通过门重定向,进入门所规定的入口点,这样可以避免低级别的程序代码从任意位置进入优先级高的程序的问题。保护模式下的中断和异常等服务程序也要从“门”进入,80386的门分为中断门,自陷门和任务门。
保护模式下表示一个中断或异常服务器程序的信息要用8个字节,包括门的种类以及xxxx:yyyy格式的入口地址。这组信息叫做”中断描述符“
保护模式下把所有的俄中断描述符放在一起组成”中断描述符“IDT,IDT不再放在固定的地址00000h处,二是采用可编程设置的方式,支持的中断数量也可以设置,为此80386处理器引入了新的48位寄存器IDTR,IDTR的高32位指定了IDT在内存中的基址(线性地址),低16位指定了IDT的长度,相当于指定了可以支持的中断数量。
在Windows中,操作系统使用动态链接库来代替中断服务程序提供系统功能,所以Win32汇编中int指令也就失去了存在的意义,这就是Win32汇编中看不到Int指令的原因。
一些特权写指令不可执行,但是一些读指令还是可以的,如sgdt,sldt,sidt
8.Win32汇编的头文件一般用inc做扩展名