打印

HotC51代言首次发布HotC51汇编数组定义头文件(HotAsm.h V1.01)

[复制链接]
2861|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
HotC51|  楼主 | 2009-2-22 16:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*------------------------------------------------------------
    HotC51汇编数组定义头文件(HotAsm.h V1.01)
最初建立时间: 2009.2.18 
最近修改时间: 2009.2.22    (正在添加之中,最终将彻底替代嵌入汇编)
增  添原  因: 为全面支持裸奔式实时操作系统HotTask51做准备
              并替代年代久远的HotIns.h/c(不在HotTask51下使用)
应        用: 可以用COM接口技术对HotC51汇编数组进行封装
              实现比嵌入汇编更为灵活和更非典之用,“汇编数组”的
              出现,将程序战场蔓延至整个代码和数据区~~~
--------------------------------------------------------------
    HotTask51汇编数组调用函数库(正在添加之中,最后形成“水库”)
--------------------------------------------------------------
    第一步:编写汇编数组的“汇编代码” 参见HotIns.h/c
--------------------------------------------------------------
HotASM (__reset_comlib__)[] = 
{//应该在C文件中编写
    HotASM_PUSH_DPL(),            
    HotASM_PUSH_DPH(),
    HotASM_RETI(),
    HotASM_CLR_A(),
    HotASM_PUSH_ACC(),            
    HotASM_PUSH_ACC(),
    HotASM_RETI(),
};
--------------------------------------------------------------
    第二步:编写普通C函数,注意它的名字与调用关系不大
--------------------------------------------------------------
void Reset()
{//此法只是演示如何替代HotIns.h/c  
    IE=0;
    DPTR = __reset_comlib__ + 5;
    _icall_(__reset_comlib__);
}
void Start()
{//此法只是演示如何替代HotIns.h/c  
    IE=0;
    PSW=0;
    _icall_(__reset_comlib__ + 4);
    _icall_(__reset_comlib__ + 4);
}
---------------------------------------------------
    第三步:编写COM接口,填入需要的C函数,
注意它的名称与调用次序关系很大,名称与调用关系不大
最后在HotAsm.h的接口里:
interface
{
    void (*HotAsm_Start)(void);
    void (*HotAsm_Reset)(void);
}IHotCom_AsmVtbl_Interface, *pIHotCom_AsmVtbl_Interface;

则在主程序里的函数名是asmLib.function.HotAsm_Reset();
----------------------------------------------------------------
IHotCom_Asm_Interface asmLib =//真实的COM接口 
{
    (pHotAsmFunction)Start,//
    (pHotAsmFunction)Reset,
};

#include "hottask51.h"
void main()
{
    asmLib.function.HotAsm_Start();//二次RETI(HotC51将做专题)
    asmLib.function.HotAsm_Reset();//软件复位
    HotTaskStart();//此时任务永远不可能启动
}              
菜农HotPower@126.com 2008.2.22 于西安大雁塔村农会授权HotC51发布
---------------------------------------------------------------*/


#include <regx52.h>
#include <absacc.h>
#include <intrins.h>

#ifndef __HotASM_H__
#define __HotASM_H__

#ifdef __cplusplus
extern "C"
{
#endif

#include "hottask51.h"//裸奔之OS系统链接头文件

/*--------------------------------------------
    汇编数组定义
--------------------------------------------*/
#define HotASM_ARRAY   code unsigned char

/*--------------------------------------------
    汇编数组成员数据类型定义
--------------------------------------------*/
#define HotASM_REG            volatile unsigned char
#define HotASM_IREG            volatile unsigned int
#define HotASM_AREG(reg)    (HotASM_REG)reg
#define HOTASM_LAREG(addr)     (HotASM_REG)addr / 256, (HotASM_REG)addr % 256

/*--------------------------------------------
    汇编数组"函数"
--------------------------------------------*/
#define HotASM(name) HotASM_ARRAY (name)

/*--------------------------------------------
    汇编数组51寄存器定义
--------------------------------------------*/
#define HotASM_REG_P0         (HotASM_REG)0x80
/*--------------------------------------------
    汇编数组P0寄存器位定义
--------------------------------------------*/
  #define HotASM_BIT_P0_0     (HotASM_REG)0x80
  #define HotASM_BIT_P0_1     (HotASM_REG)0x81
  #define HotASM_BIT_P0_2     (HotASM_REG)0x82
  #define HotASM_BIT_P0_3     (HotASM_REG)0x83
  #define HotASM_BIT_P0_4     (HotASM_REG)0x84
  #define HotASM_BIT_P0_5     (HotASM_REG)0x85
  #define HotASM_BIT_P0_6     (HotASM_REG)0x86
  #define HotASM_BIT_P0_7     (HotASM_REG)0x87
    #define HotASM_REG_SP     (HotASM_REG)0x81
    #define HotASM_REG_DPL    (HotASM_REG)0x82
    #define HotASM_REG_DPH    (HotASM_REG)0x83
    #define HotASM_REG_PCON (HotASM_REG)0x87
/*--------------------------------------------
    汇编数组PCON寄存器位定义(不能位寻址)
--------------------------------------------*/
  #define HotASM_BIT_PCON_IDL     (HotASM_REG)0x01
  #define HotASM_BIT_PCON_STOP    (HotASM_REG)0x02
  #define HotASM_BIT_PCON_PD    (HotASM_REG)0x03    /* Alternate definition */
  #define HotASM_BIT_PCON_GF0   (HotASM_REG)0x08
  #define HotASM_BIT_PCON_GF1   (HotASM_REG)0x04

  #define HotASM_BIT_PCON_SMOD  (HotASM_REG)0x80
#define HotASM_REG_TCON        (HotASM_REG)0x88
  #define HotASM_BIT_TCON_0        (HotASM_REG)0x88
  #define HotASM_BIT_TCON_1        (HotASM_REG)0x89
  #define HotASM_BIT_TCON_2        (HotASM_REG)0x8A
  #define HotASM_BIT_TCON_3        (HotASM_REG)0x8B
  #define HotASM_BIT_TCON_4        (HotASM_REG)0x8C
  #define HotASM_BIT_TCON_5        (HotASM_REG)0x8D
  #define HotASM_BIT_TCON_6        (HotASM_REG)0x8E
  #define HotASM_BIT_TCON_7        (HotASM_REG)0x8F

  #define HotASM_BIT_TCON_IT0    (HotASM_REG)0x88
  #define HotASM_BIT_TCON_IE0    (HotASM_REG)0x89
  #define HotASM_BIT_TCON_IT1    (HotASM_REG)0x8A
  #define HotASM_BIT_TCON_IE1    (HotASM_REG)0x8B
  #define HotASM_BIT_TCON_TR0    (HotASM_REG)0x8C
  #define HotASM_BIT_TCON_TF0    (HotASM_REG)0x8D
  #define HotASM_BIT_TCON_TR1    (HotASM_REG)0x8E
  #define HotASM_BIT_TCON_TF1    (HotASM_REG)0x8F
#define HotASM_REG_TMOD        (HotASM_REG)0x89
/*--------------------------------------------
    汇编数组TMOD寄存器位定义(不能位寻址)
--------------------------------------------*/
  #define HotASM_BIT_TMOD_0 (HotASM_REG)0x01
  #define HotASM_BIT_TMOD_1 (HotASM_REG)0x02
  #define HotASM_BIT_TMOD_2 (HotASM_REG)0x04
  #define HotASM_BIT_TMOD_3 (HotASM_REG)0x08
  #define HotASM_BIT_TMOD_4 (HotASM_REG)0x10
  #define HotASM_BIT_TMOD_5 (HotASM_REG)0x20
  #define HotASM_BIT_TMOD_6 (HotASM_REG)0x40
  #define HotASM_BIT_TMOD_7 (HotASM_REG)0x80

    #define HotASM_REG_TL0    (HotASM_REG)0x8a
    #define HotASM_REG_TH0    (HotASM_REG)0x8c
    #define HotASM_REG_TL1    (HotASM_REG)0x8b
    #define HotASM_REG_TH1    (HotASM_REG)0x8d
#define HotASM_REG_P1         (HotASM_REG)0x90
/*--------------------------------------------
    汇编数组P1寄存器位定义
--------------------------------------------*/
  #define HotASM_BIT_P1_0    (HotASM_REG)0x90
  #define HotASM_BIT_P1_1    (HotASM_REG)0x91
  #define HotASM_BIT_P1_2    (HotASM_REG)0x92
  #define HotASM_BIT_P1_3    (HotASM_REG)0x93
  #define HotASM_BIT_P1_4    (HotASM_REG)0x94
  #define HotASM_BIT_P1_5    (HotASM_REG)0x95
  #define HotASM_BIT_P1_6    (HotASM_REG)0x96
  #define HotASM_BIT_P1_7    (HotASM_REG)0x97
#define HotASM_REG_SCON        (HotASM_REG)0x98
  #define HotASM_BIT_SCON_0 (HotASM_REG)0x98
  #define HotASM_BIT_SCON_1 (HotASM_REG)0x99
  #define HotASM_BIT_SCON_2 (HotASM_REG)0x9A
  #define HotASM_BIT_SCON_3 (HotASM_REG)0x9B
  #define HotASM_BIT_SCON_4 (HotASM_REG)0x9C
  #define HotASM_BIT_SCON_5 (HotASM_REG)0x9D
  #define HotASM_BIT_SCON_6 (HotASM_REG)0x9E
  #define HotASM_BIT_SCON_7 (HotASM_REG)0x9F

  #define HotASM_BIT_SCON_RI     (HotASM_REG)0x98
  #define HotASM_BIT_SCON_TI     (HotASM_REG)0x99
  #define HotASM_BIT_SCON_RB8     (HotASM_REG)0x9A
  #define HotASM_BIT_SCON_TB8     (HotASM_REG)0x9B
  #define HotASM_BIT_SCON_REN     (HotASM_REG)0x9C
  #define HotASM_BIT_SCON_SM2     (HotASM_REG)0x9D
  #define HotASM_BIT_SCON_SM1     (HotASM_REG)0x9E
  #define HotASM_BIT_SCON_SM0     (HotASM_REG)0x9F
#define HotASM_REG_SBUF        (HotASM_REG)0x99
#define HotASM_REG_P2         (HotASM_REG)0xa0
/*--------------------------------------------
    汇编数组P2寄存器位定义
--------------------------------------------*/
  #define HotASM_BIT_P2_0    (HotASM_REG)0xa0
  #define HotASM_BIT_P2_1    (HotASM_REG)0xa1
  #define HotASM_BIT_P2_2    (HotASM_REG)0xa2
  #define HotASM_BIT_P2_3    (HotASM_REG)0xa3
  #define HotASM_BIT_P2_4    (HotASM_REG)0xa4
  #define HotASM_BIT_P2_5    (HotASM_REG)0xa5
  #define HotASM_BIT_P2_6    (HotASM_REG)0xa6
  #define HotASM_BIT_P2_7    (HotASM_REG)0xa7
#define HotASM_REG_IE        (HotASM_REG)0xa8
  #define HotASM_BIT_IE0    (HotASM_REG)0xa8
  #define HotASM_BIT_IE1    (HotASM_REG)0xa9
  #define HotASM_BIT_IE2    (HotASM_REG)0xaa
  #define HotASM_BIT_IE3    (HotASM_REG)0xab
  #define HotASM_BIT_IE4    (HotASM_REG)0xac
  #define HotASM_BIT_IE5    (HotASM_REG)0xad
  #define HotASM_BIT_IE6    (HotASM_REG)0xae
  #define HotASM_BIT_IE7    (HotASM_REG)0xaf

  #define HotASM_BIT_EX0    (HotASM_REG)0xa8
  #define HotASM_BIT_ET0    (HotASM_REG)0xa9
  #define HotASM_BIT_EX1    (HotASM_REG)0xaa
  #define HotASM_BIT_ET1    (HotASM_REG)0xab
  #define HotASM_BIT_ES        (HotASM_REG)0xac
  #define HotASM_BIT_ET2    (HotASM_REG)0xad
//  #define HotASM_BIT_IE6    (HotASM_REG)0xae
  #define HotASM_BIT_EA        (HotASM_REG)0xaf
#define HotASM_REG_P3         (HotASM_REG)0xb0
/*--------------------------------------------
    汇编数组P3寄存器位定义
--------------------------------------------*/
  #define HotASM_BIT_P3_0    (HotASM_REG)0xb0
  #define HotASM_BIT_P3_1    (HotASM_REG)0xb1
  #define HotASM_BIT_P3_2    (HotASM_REG)0xb2
  #define HotASM_BIT_P3_3    (HotASM_REG)0xb3
  #define HotASM_BIT_P3_4    (HotASM_REG)0xb4
  #define HotASM_BIT_P3_5    (HotASM_REG)0xb5
  #define HotASM_BIT_P3_6    (HotASM_REG)0xb6
  #define HotASM_BIT_P3_7    (HotASM_REG)0xb7
#define HotASM_REG_IP         (HotASM_REG)0xb8
  #define HotASM_BIT_IP_0    (HotASM_REG)0xb8
  #define HotASM_BIT_IP_1    (HotASM_REG)0xb9
  #define HotASM_BIT_IP_2    (HotASM_REG)0xba
  #define HotASM_BIT_IP_3    (HotASM_REG)0xbb
  #define HotASM_BIT_IP_4    (HotASM_REG)0xbc
  #define HotASM_BIT_IP_5    (HotASM_REG)0xbd
  #define HotASM_BIT_IP_6    (HotASM_REG)0xbe
  #define HotASM_BIT_IP_7    (HotASM_REG)0xbf
#define HotASM_REG_PSW        (HotASM_REG)0xd0
  #define HotASM_BIT_PSW_0    (HotASM_REG)0xd0
  #define HotASM_BIT_PSW_1    (HotASM_REG)0xd1
  #define HotASM_BIT_PSW_2    (HotASM_REG)0xd2
  #define HotASM_BIT_PSW_3    (HotASM_REG)0xd3
  #define HotASM_BIT_PSW_4    (HotASM_REG)0xd4
  #define HotASM_BIT_PSW_5    (HotASM_REG)0xd5
  #define HotASM_BIT_PSW_6    (HotASM_REG)0xd6
  #define HotASM_BIT_PSW_7    (HotASM_REG)0xd7

  #define HotASM_BIT_PSW_PX0    (HotASM_REG)0xd0
  #define HotASM_BIT_PSW_PT0    (HotASM_REG)0xd1
  #define HotASM_BIT_PSW_PX1    (HotASM_REG)0xd2
  #define HotASM_BIT_PSW_PT1    (HotASM_REG)0xd3
  #define HotASM_BIT_PSW_PS        (HotASM_REG)0xd4
  #define HotASM_BIT_PSW_PT2    (HotASM_REG)0xd5
//  #define HotASM_BIT_PSW_6        (HotASM_REG)0xd6
//  #define HotASM_BIT_PSW_7        (HotASM_REG)0xd7

  #define HotASM_BIT_PSW_P        (HotASM_REG)0xd0
  #define HotASM_BIT_PSW_F1        (HotASM_REG)0xd1
  #define HotASM_BIT_PSW_OV        (HotASM_REG)0xd2
  #define HotASM_BIT_PSW_RS0    (HotASM_REG)0xd3
  #define HotASM_BIT_PSW_RS1     (HotASM_REG)0xd4
  #define HotASM_BIT_PSW_F0        (HotASM_REG)0xd5
  #define HotASM_BIT_PSW_AC        (HotASM_REG)0xd6
  #define HotASM_BIT_PSW_C        (HotASM_REG)0xd7
#define HotASM_REG_T2CON    (HotASM_REG)0xc8
    #define HotASM_REG_TH2    (HotASM_REG)0xcd
    #define HotASM_REG_TL2    (HotASM_REG)0xcc
    #define HotASM_REG_RCAP2H    (HotASM_REG)0xcb
    #define HotASM_REG_RCAP2L    (HotASM_REG)0xca
#define HotASM_REG_ACC         (HotASM_REG)0xe0
/*--------------------------------------------
    汇编数组ACC寄存器位定义
--------------------------------------------*/
  #define HotASM_BIT_ACC_0    (HotASM_REG)0xe0
  #define HotASM_BIT_ACC_1    (HotASM_REG)0xe1
  #define HotASM_BIT_ACC_2    (HotASM_REG)0xe2
  #define HotASM_BIT_ACC_3    (HotASM_REG)0xe3
  #define HotASM_BIT_ACC_4    (HotASM_REG)0xe4
  #define HotASM_BIT_ACC_5    (HotASM_REG)0xe5
  #define HotASM_BIT_ACC_6    (HotASM_REG)0xe6
  #define HotASM_BIT_ACC_7    (HotASM_REG)0xe7
#define HotASM_REG_B         (HotASM_REG)0xf0
/*--------------------------------------------
    汇编数组B寄存器位定义
--------------------------------------------*/
  #define HotASM_BIT_B_0    (HotASM_REG)0xf0
  #define HotASM_BIT_B_1    (HotASM_REG)0xf1
  #define HotASM_BIT_B_2    (HotASM_REG)0xf2
  #define HotASM_BIT_B_3    (HotASM_REG)0xf3
  #define HotASM_BIT_B_4    (HotASM_REG)0xf4
  #define HotASM_BIT_B_5    (HotASM_REG)0xf5
  #define HotASM_BIT_B_6    (HotASM_REG)0xf6
  #define HotASM_BIT_B_7    (HotASM_REG)0xf7
/*--------------------------------------------
    汇编宏指令操作码定义
--------------------------------------------*/

#define HotASM_Code_LJMP     (HotASM_REG)0x02
#define HotASM_Code_SJMP     (HotASM_REG)0x80

#define HotASM_Code_LCALL     (HotASM_REG)0x12


#define HotASM_Code_PUSH     (HotASM_REG)0xc0
#define HotASM_Code_INC      (HotASM_REG)0x05
#define HotASM_Code_DEC      (HotASM_REG)0x15

#define HotASM_Code_MOV_DPTR     (HotASM_REG)0x90

/*--------------------------------------------
    汇编宏指令
--------------------------------------------*/
#define HotASM_NOP()               (HotASM_REG)0x00
#define HotASM_RR_A()           (HotASM_REG)0x03
#define HotASM_INC_A()           (HotASM_REG)0x04

#define HotASM_CLR_A()           (HotASM_REG)0xe4

#define HotASM_RET()               (HotASM_REG)0x22
#define HotASM_RETI()           (HotASM_REG)0x32

#define HotASM_MOV_DPTR(addr)     HotASM_Code_MOV_DPTR, HOTASM_LAREG(addr)

#define HotASM_LJMP(addr)         HotASM_Code_LJMP, HOTASM_LAREG(addr)

#define HotASM_LCALL(addr)         HotASM_Code_LCALL, HOTASM_LAREG(addr)
                           
#define HotASM_PUSH_(reg)         HotASM_Code_PUSH, HotASM_AREG(reg)

#define HotASM_PUSH_PSW()         HotASM_Code_PUSH, HotASM_REG_PSW
#define HotASM_PUSH_ACC()         HotASM_Code_PUSH, HotASM_REG_ACC
#define HotASM_PUSH_B()         HotASM_Code_PUSH, HotASM_REG_B
#define HotASM_PUSH_DPL()         HotASM_Code_PUSH, HotASM_REG_DPL
#define HotASM_PUSH_DPH()         HotASM_Code_PUSH, HotASM_REG_DPH


#define HotASM_Code_INC_(reg)     HotASM_Code_INC,HotASM_AREG(reg) 
    #define HotASM_INC_SP()     HotASM_Code_INC, HotASM_REG_SP
#define HotASM_Code_DEC_(reg)     HotASM_Code_DEC,HotASM_AREG(reg) 
    #define HotASM_DEC_SP()     HotASM_Code_DEC, HotASM_REG_SP

/*--------------------------------------
    HotTask51汇编数组调用函数接口定义
--------------------------------------*/
#define interface typedef struct//COM接口定义

typedef void (*pHotAsmFunction)(void);//函数指针

interface
{
    void (*HotAsm_Start)(void);
    void (*HotAsm_Reset)(void);
}IHotCom_AsmVtbl_Interface, *pIHotCom_AsmVtbl_Interface;

interface
{
    IHotCom_AsmVtbl_Interface function;
}IHotCom_Asm_Interface, *pIHotCom_Asm_Interface;

extern IHotCom_Asm_Interface asmLib;

extern HotASM_ARRAY (__reset_comlib__)[];

/*--------------------------------------
    HotTask51汇编数组存放任务表定义
--------------------------------------*/
//extern HotASM_ARRAY HotTaskTable0[];
//extern HotASM_ARRAY HotTaskTable1[];


#ifdef __cplusplus
}
#endif
#endif//__HotASM_H__

相关帖子

沙发
HotC51|  楼主 | 2009-2-22 18:49 | 只看该作者

有人要晕~~~刚和吴教授谈起了Java虚拟机,俺认为汇编数组有


吴教授搞了多年的嵌入式应用及教学,学子可谓是高手之高手~~~
俺亲眼看到他的一个女弟子招聘到航天二所还不满意,因为一所也抢她~~~
当时俺很“害羞”,整天都是“满街地裸奔”~~~
下午我发布了首版的51汇编数组~~~估计有很多人晕~~~
至少对“汇编数组”的理解为“汇编语言里的数组”,但少了“语言”两字,
则有天地之别,因为前者是在数组了存放汇编的执行代码,后者是如何在汇编
语言里操作连续存放的数据。
和吴教授谈心后,他对OS的环境提出了问题,即如何让OS与平台无关~~~
俺可能理解有误,等教授看完今天俺发布的汇编数组后再看他的论点~~~
若菜农的理念“超前”,则今天的“汇编数组”可能就是明天的“MCU虚拟机”
因为俺的“汇编数组”就是跨(编译器)“平台”的~~~
俺若再向前迈出一步,来个各类MCU汇编代码的“汇编数组”总汇,
那么再用COM接口封装分类与COM挂接,那就不是实现了无教授的愿望了吗??
哈哈~~~农村交通闭塞,菜农研究数年的玩意竟会有“未来之妙用”???
等吴教授的回音~~~
 
 
**来自:http://www.qqread.com/java/w872354600.html

Java技术与Java虚拟机 

  说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API)。它们的关系如下图所示:

http://www.qqread.com/ArtImage/20060214/pp5_1.gif
图1 Java四个方面的关系

  运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件)。最后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执行。从上图也可以看出Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上。这个平台的结构如下图所示:

http://www.qqread.com/ArtImage/20060214/pp5_2.gif 
(点击查看原图)


  在Java平台的结构中, 可以看出,Java虚拟机(JVM) 处在核心的位置,是程序与底层操作系统和硬件无关的关键。它的下方是移植接口,移植接口由两部分组成:适配器和Java操作系统, 其中依赖于平台的部分称为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;在JVM 的上方是Java的基本类库和扩展类库以及它们的API, 利用Java API编写的应用程序(application) 和小程序(Java applet) 可以在任何Java平台上运行而无需考虑底层平台, 就是因为有Java虚拟机(JVM)实现了程序与操作系统的分离,从而实现了Java 的平台无关性。 

  那么到底什么是Java虚拟机(JVM)呢?通常我们谈论JVM时,我们的意思可能是: 

  对JVM规范的的比较抽象的说明; 
  对JVM的具体实现; 
  在程序运行期间所生成的一个JVM实例。 

  对JVM规范的的抽象说明是一些概念的集合,它们已经在书《The Java Virtual Machine Specification》(《Java虚拟机规范》)中被详细地描述了;对JVM的具体实现要么是软件,要么是软件和硬件的组合,它已经被许多生产厂商所实现,并存在于多种平台之上;运行Java程序的任务由JVM的运行期实例单个承担。在本文中我们所讨论的Java虚拟机(JVM)主要针对第三种情况而言。它可以被看成一个想象中的机器,在实际的计算机上通过软件模拟来实现,有自己想象中的硬件,如处理器、堆栈、寄存器等,还有自己相应的指令系统。

  JVM在它的生存周期中有一个明确的任务,那就是运行Java程序,因此当Java程序启动的时候,就产生JVM的一个实例;当程序运行结束的时候,该实例也跟着消失了。下面我们从JVM的体系结构和它的运行过程这两个方面来对它进行比较深入的研究。

Java虚拟机的体系结构

  刚才已经提到,JVM可以由不同的厂商来实现。由于厂商的不同必然导致JVM在实现上的一些不同,然而JVM还是可以实现跨平台的特性,这就要归功于设计JVM时的体系结构了。

  我们知道,一个JVM实例的行为不光是它自己的事,还涉及到它的子系统、存储区域、数据类型和指令这些部分,它们描述了JVM的一个抽象的内部体系结构,其目的不光规定实现JVM时它内部的体系结构,更重要的是提供了一种方式,用于严格定义实现时的外部行为。每个JVM都有两种机制,一个是装载具有合适名称的类(类或是接口),叫做类装载子系统;另外的一个负责执行包含在已装载的类或接口中的指令,叫做运行引擎。每个JVM又包括方法区、堆、Java栈、程序计数器和本地方法栈这五个部分,这几个部分和类装载机制与运行引擎机制一起组成的体系结构图为:

http://www.qqread.com/ArtImage/20060214/pp5_3.gif
图3 JVM的体系结构

  JVM的每个实例都有一个它自己的方法域和一个堆,运行于JVM内的所有的线程都共享这些区域;当虚拟机装载类文件的时候,它解析其中的二进制数据所包含的类信息,并把它们放到方法域中;当程序运行的时候,JVM把程序初始化的所有对象置于堆上;而每个线程创建的时候,都会拥有自己的程序计数器和Java栈,其中程序计数器中的值指向下一条即将被执行的指令,线程的Java栈则存储为该线程调用Java方法的状态;本地方法调用的状态被存储在本地方法栈,该方法栈依赖于具体的实现。

  下面分别对这几个部分进行说明。

  执行引擎处于JVM的核心位置,在Java虚拟机规范中,它的行为是由指令集所决定的。尽管对于每条指令,规范很详细地说明了当JVM执行字节码遇到指令时,它的实现应该做什么,但对于怎么做却言之甚少。Java虚拟机支持大约248个字节码。每个字节码执行一种基本的CPU运算,例如,把一个整数加到寄存器,子程序转移等。Java指令集相当于Java程序的汇编语言

  Java指令集中的指令包含一个单字节的操作符,用于指定要执行的操作,还有0个或多个操作数,提供操作所需的参数或数据。许多指令没有操作数,仅由一个单字节的操作符构成。

  虚拟机的内层循环的执行过程如下: 

do{ 
取一个操作符字节; 
根据操作符的值执行一个动作; 
}while(程序未结束)

  由于指令系统的简单性,使得虚拟机执行的过程十分简单,从而有利于提高执行的效率。指令中操作数的数量和大小是由操作符决定的。如果操作数比一个字节大,那么它存储的顺序是高位字节优先。例如,一个16位的参数存放时占用两个字节,其值为: 

  第一个字节*256+第二个字节字节码。 

  指令流一般只是字节对齐的。指令tableswitch和lookup是例外,在这两条指令内部要求强制的4字节边界对齐。 

  对于本地方法接口,实现JVM并不要求一定要有它的支持,甚至可以完全没有。Sun公司实现Java本地接口(JNI)是出于可移植性的考虑,当然我们也可以设计出其它的本地接口来代替Sun公司的JNI。但是这些设计与实现是比较复杂的事情,需要确保垃圾回收器不会将那些正在被本地方法调用的对象释放掉。 

  Java的堆是一个运行时数据区,类的实例(对象)从中分配空间,它的管理是由垃圾回收来负责的:不给程序员显式释放对象的能力。Java不规定具体使用的垃圾回收算法,可以根据系统的需求使用各种各样的算法。 

  Java方法区与传统语言中的编译后代码或是Unix进程中的正文段类似。它保存方法代码(编译后的java代码)和符号表。在当前的Java实现中,方法代码不包括在垃圾回收堆中,但计划在将来的版本中实现。每个类文件包含了一个Java类或一个Java界面的编译后的代码。可以说类文件是Java语言的执行代码文件。为了保证类文件的平台无关性,Java虚拟机规范中对类文件的格式也作了详细的说明。其具体细节请参考Sun公司的Java虚拟机规范。 

  Java虚拟机的寄存器用于保存机器的运行状态,与微处理器中的某些专用寄存器类似。Java虚拟机的寄存器有四种: 

  pc: Java程序计数器; 
  optop: 指向操作数栈顶端的指针; 
  frame: 指向当前执行方法的执行环境的指针;。 
  vars: 指向当前执行方法的局部变量区第一个变量的指针。 

  在上述体系结构图中,我们所说的是第一种,即程序计数器,每个线程一旦被创建就拥有了自己的程序计数器。当线程执行Java方法的时候,它包含该线程正在被执行的指令的地址。但是若线程执行的是一个本地的方法,那么程序计数器的值就不会被定义。 

  Java虚拟机的栈有三个区域:局部变量区、运行环境区、操作数区。

  局部变量区

  每个Java方法使用一个固定大小的局部变量集。它们按照与vars寄存器的字偏移量来寻址。局部变量都是32位的。长整数和双精度浮点数占据了两个局部变量的空间,却按照第一个局部变量的索引来寻址。(例如,一个具有索引n的局部变量,如果是一个双精度浮点数,那么它实际占据了索引n和n+1所代表的存储空间)虚拟机规范并不要求在局部变量中的64位的值是64位对齐的。虚拟机提供了把局部变量中的值装载到操作数栈的指令,也提供了把操作数栈中的值写入局部变量的指令。

  运行环境区

  在运行环境中包含的信息用于动态链接,正常的方法返回以及异常捕捉。 

  动态链接 

  运行环境包括对指向当前类和当前方法的解释器符号表的指针,用于支持方法代码的动态链接。方法的class文件代码在引用要调用的方法和要访问的变量时使用符号。动态链接把符号形式的方法调用翻译成实际方法调用,装载必要的类以解释还没有定义的符号,并把变量访问翻译成与这些变量运行时的存储结构相应的偏移地址。动态链接方法和变量使得方法中使用的其它类的变化不会影响到本程序的代码。 

  正常的方法返回 

  如果当前方法正常地结束了,在执行了一条具有正确类型的返回指令时,调用的方**得到一个返回值。执行环境在正常返回的情况下用于恢复调用者的寄存器,并把调用者的程序计数器增加一个恰当的数值,以跳过已执行过的方法调用指令,然后在调用者的执行环境中继续执行下去。 

  异常捕捉 

  异常情况在Java中被称作Error(错误)或Exception(异常),是Throwable类的子类,在程序中的原因是:①动态链接错,如无法找到所需的class文件。②运行时错,如对一个空指针的引用。程序使用了throw语句。 

  当异常发生时,Java虚拟机采取如下措施: 

  检查与当前方法相联系的catch子句表。每个catch子句包含其有效指令范围,能够处理的异常类型,以及处理异常的代码块地址。 

  与异常相匹配的catch子句应该符合下面的条件:造成异常的指令在其指令范围之内,发生的异常类型是其能处理的异常类型的子类型。如果找到了匹配的catch子句,那么系统转移到指定的异常处理块处执行;如果没有找到异常处理块,重复寻找匹配的catch子句的过程,直到当前方法的所有嵌套的catch子句都被检查过。 

  由于虚拟机从第一个匹配的catch子句处继续执行,所以catch子句表中的顺序是很重要的。因为Java代码是结构化的,因此总可以把某个方法的所有的异常处理器都按序排列到一个表中,对任意可能的程序计数器的值,都可以用线性的顺序找到合适的异常处理块,以处理在该程序计数器值下发生的异常情况。 

  如果找不到匹配的catch子句,那么当前方法得到一个"未截获异常"的结果并返回到当前方法的调用者,好像异常刚刚在其调用者中发生一样。如果在调用者中仍然没有找到相应的异常处理块,那么这种错误将被传播下去。如果错误被传播到最顶层,那么系统将调用一个缺省的异常处理块。 

  操作数栈区

  机器指令只从操作数栈中取操作数,对它们进行操作,并把结果返回到栈中。选择栈结构的原因是:在只有少量寄存器或非通用寄存器的机器(如Intel486)上,也能够高效地模拟虚拟机的行为。操作数栈是32位的。它用于给方法传递参数,并从方法接收结果,也用于支持操作的参数,并保存操作的结果。例如,iadd指令将两个整数相加。相加的两个整数应该是操作数栈顶的两个字。这两个字是由先前的指令压进堆栈的。这两个整数将从堆栈弹出、相加,并把结果压回到操作数栈中。 

  每个原始数据类型都有专门的指令对它们进行必须的操作。每个操作数在栈中需要一个存储位置,除了long和double型,它们需要两个位置。操作数只能被适用于其类型的操作符所操作。例如,压入两个int类型的数,如果把它们当作是一个long类型的数则是非法的。在Sun的虚拟机实现中,这个限制由字节码验证器强制实行。但是,有少数操作(操作符dupe和swap),用于对运行时数据区进行操作时是不考虑类型的。 

  本地方法栈,当一个线程调用本地方法时,它就不再受到虚拟机关于结构和安全限制方面的约束,它既可以访问虚拟机的运行期数据区,也可以使用本地处理器以及任何类型的栈。例如,本地栈是一个C语言的栈,那么当C程序调用C函数时,函数的参数以某种顺序被压入栈,结果则返回给调用函数。在实现Java虚拟机时,本地方法接口使用的是C语言的模型栈,那么它的本地方法栈的调度与使用则完全与C语言的栈相同。


Java虚拟机的运行过程

  上面对虚拟机的各个部分进行了比较详细的说明,下面通过一个具体的例子来分析它的运行过程。

  虚拟机通过调用某个指定类的方法main启动,传递给main一个字符串数组参数,使指定的类被装载,同时链接该类所使用的其它的类型,并且初始化它们。例如对于程序:

class HelloApp 
{
 public static void main(String[] args) 
 {
  System.out.println("Hello World!"); 
  for (int i = 0; i < args.length; i++ )
  {
   System.out.println(args);
  }
 }
}

  编译后在命令行模式下键入: java HelloApp run virtual machine 

  将通过调用HelloApp的方法main来启动java虚拟机,传递给main一个包含三个字符串"run"、"virtual"、"machine"的数组。现在我们略述虚拟机在执行HelloApp时可能采取的步骤。 

  开始试图执行类HelloApp的main方法,发现该类并没有被装载,也就是说虚拟机当前不包含该类的二进制代表,于是虚拟机使用ClassLoader试图寻找这样的二进制代表。如果这个进程失败,则抛出一个异常。类被装载后同时在main方法被调用之前,必须对类HelloApp与其它类型进行链接然后初始化。链接包含三个阶段:检验,准备和解析。检验检查被装载的主类的符号和语义,准备则创建类或接口的静态域以及把这些域初始化为标准的默认值,解析负责检查主类对其它类或接口的符号引用,在这一步它是可选的。类的初始化是对类中声明的静态初始化函数和静态域的初始化构造方法的执行。一个类在初始化之前它的父类必须被初始化。整个过程如下:

http://www.qqread.com/ArtImage/20060214/pp5_4.gif 
(点击查看原图)

图4:虚拟机的运行过程
  结束语

  本文通过对JVM的体系结构的深入研究以及一个Java程序执行时虚拟机的运行过程的详细分析,意在剖析清楚Java虚拟机的机理。 

 
 

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

306

帖子

0

粉丝