被调用程序入口地址

COBOL程序调用详解

使用COBOL语言编写的程序调用通常只用提供被调用程序的程序名以及所传递的参数。然而,真正在系统内部实现的程序调用,则按以下步骤执行。

q      保护现场

q      访问被调用程序的入口地址

q      进入并执行被调用程序

q      退出被调用程序

q      恢复现场

由此可见,被调用程序的入口地址在程序调用中是十分重要的。该入口地址决定了在何处能够访问到被调用程序。通常,在COBOL高级语言中,被调用程序的入口地址是通过程序名反映出来的。例如,下面为一段被调用程序代码。

IDENTIFICATION   DIVISION.

PROGRAM-ID      CALLED-PGM.

AUTHER           XXX.

*

ENVIRONMENT   DIVISION.

*

DATA  DIVISION.

WORKING STORAGE SECTION.

……

 LINKAGE SECTION.

 77  CALLED-PARM    PIC  X.

*

PROCEDURE   DIVISION  USING  CALLED-PARM.

……

GOBACK.

以上程序的入口地址直接通过编译后的程序名反映出来。该程序名为CALLED-PGM。因此,在主调用程序中使用CALL语句对其调用的方式如下。

   CALL  ‘CALLED-PGM’  USING  CALLING-PARM.

除此之外,还可在被调用程序中通过ENTRY语句指定选择性入口地址。主调用程序同样可以通过该选择性入口地址实现程序的调用。当在以上被调用程序中通过ENTRY语句指定选择性入口地址时,该程序代码如下。

IDENTIFICATION   DIVISION.

PROGRAM-ID      CALLED-PGM.

AUTHER           XXX.

*

ENVIRONMENT   DIVISION.

*

DATA  DIVISION.

WORKING STORAGE SECTION.

……

 LINKAGE SECTION.

 77  CALLED-PARM    PIC  X.

*

PROCEDURE   DIVISION  USING  CALLED-PARM.

……

GOBACK.

ENTRY  ‘ALTENTRY’   USING  CALLED-PARM.

……

  GOBACK.

此时,在主调用程序中,便可通过使用ENTRY语句定义的选择性入口地址实现程序调用。调用方式如下。

   CALL  ‘ALTENTRY’   USING  CALLING-PARM.

系统调用入口程序是用户程序与操作系统内核之间的桥梁,它负责处理用户程序发起的系统调用请求,将用户态的执行环境切换到内核态,让内核执行相应的系统调用服务。以下从几个方面介绍系统调用入口程序: ### 功能 - **用户态到内核态的切换**:当用户程序执行系统调用时,会触发一个软中断指令(如 x86 架构下的 `int 0x80` 或 `syscall`),系统调用入口程序接收到该指令后,会进行特权级的切换,从用户态进入内核态,以便执行特权操作[^1]。 - **参数传递与验证**:用户程序通常会通过寄存器或栈来传递系统调用的参数,系统调用入口程序会负责收集这些参数,并对其进行验证,确保参数的合法性和安全性,防止恶意用户利用非法参数破坏系统。 - **系统调用号的解析**:每个系统调用都有一个唯一的系统调用号,用户程序在发起系统调用时会将系统调用号传递给内核。系统调用入口程序会根据这个系统调用号,查找对应的内核服务例程,并跳转到该例程执行。 - **上下文保存与恢复**:在进入内核态执行系统调用之前,系统调用入口程序会保存用户程序的上下文信息(如寄存器值、程序计数器等),以便在系统调用执行完毕后,能够正确地恢复用户程序的执行环境,继续从断点处执行。 ### 工作流程 1. **触发系统调用**:用户程序通过执行软中断指令(如 `int 0x80` 或 `syscall`)触发系统调用,将控制权转移到系统调用入口程序。 2. **保存上下文**:系统调用入口程序保存当前用户程序的上下文信息,包括通用寄存器、指令指针、标志寄存器等,以便后续恢复。 3. **获取系统调用号和参数**:从寄存器或栈中获取用户程序传递的系统调用号和参数。 4. **查找系统调用服务例程**:根据系统调用号,在内核的系统调用表中查找对应的服务例程。 5. **调用服务例程**:跳转到找到的服务例程执行,完成具体的系统调用操作。 6. **恢复上下文**:系统调用服务例程执行完毕后,系统调用入口程序恢复之前保存的用户程序上下文信息。 7. **返回用户态**:将控制权交还给用户程序,继续执行后续的指令。 ### 示例代码(以 Linux 内核为例) 以下是一个简化的 Linux 内核系统调用入口程序的伪代码示例,展示了基本的工作流程: ```c // 系统调用入口程序 void system_call_entry() { // 保存用户程序上下文 save_user_context(); // 获取系统调用号 int syscall_number = get_syscall_number(); // 获取系统调用参数 int* params = get_syscall_params(); // 验证参数 if (!validate_params(params)) { // 参数不合法,处理错误 handle_error(); restore_user_context(); return_to_user_mode(); } // 查找系统调用服务例程 void (*syscall_handler)() = find_syscall_handler(syscall_number); if (syscall_handler != NULL) { // 调用系统调用服务例程 int result = syscall_handler(params); // 将结果返回给用户程序 set_return_value(result); } else { // 未找到对应的系统调用服务例程,处理错误 handle_error(); } // 恢复用户程序上下文 restore_user_context(); // 返回用户态 return_to_user_mode(); } ``` ### 与硬件的交互 系统调用入口程序与硬件的交互主要体现在中断机制上。当用户程序执行软中断指令时,会触发硬件的中断机制,CPU 会暂停当前的执行流程,跳转到中断向量表中对应的中断处理程序入口地址,也就是系统调用入口程序的起始地址。系统调用入口程序利用硬件提供的特权级切换机制,实现从用户态到内核态的转换。 ### 不同架构的差异 不同的硬件架构在系统调用的实现上可能存在差异,主要体现在软中断指令、寄存器使用、系统调用表的组织方式等方面。例如,x86 架构使用 `int 0x80` 或 `syscall` 指令触发系统调用,而 ARM 架构使用 `svc` 指令。系统调用入口程序需要根据不同的架构进行相应的调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值