IIS7的处理程序映射对于.net来说那些是可以不要的?可以删除掉么?

IIS7的处理程序映射对于.net来说那些是可以不要的?可以删除掉么?,第1张

那些都是举搏核心module和handler,不亩猛用杞人忧天了。

如果没用到.asp的话,可以禁用

如果你是webform的话,.aspx, .axd, .ashx不能禁用

用到webservice的话,.asmx, .soap不迅答桥能禁用

用到wcf的话,.svc, .soap不能禁用

如果是mvc程序的话,.cshtml不能禁用

StaticFile不能禁用

问题表现: 某个应用在调用wcf服务时,日志提示"405 method not allowed"

开始以为是程序的问题,后来发现在别的服务器上安装使用都没有问题,猜测可能是IIS环境的问题。

百度了一下,得出的结论是:一般IIS默认能处理静态的htm,html文件 ,以埋激雀及动态铅液的脚本 asp,aspx 文件,如果要处理php或其他类型的脚本语言,必须做好ISAPI映射,于是打开IIS,找到提供上述RisWebService.svc服务的站点,点击“处理程序映射”

观察路径这一列,发现没有.svc的路径映射,所以IIS无法识别程序中的一般处理程序(*.svc),因此就报了标题中的错误。可能是在安装IIS过程中安装ASP.net功能安全不全。

解决弯早办法:找到NET4安装目录: %windir%\Microsoft.NET\Framework64\v4.0.30319,

cmd运行命令 aspnet_regiis -i,

安装完之后,再次查看IIS程序映射,发现增加了.svc路径,问题解决。

发生异常时,异常处理程序可能需要确定处理器是在 ARM 状态还是在 Thumb 状返肆态。

特别是 SVC 处理程序,更需要读取处理器状态。 通过检查 SPSR 的 T 位可确定处理器状态。 该位在 Thumb 状态时为 1,在 ARM 状态时为 0。

ARM 和 Thumb 指令集均有 SVC 指令。 在 Thumb 状态下调用 SVC 时,必须考虑以下情况:

指令的地址在 lr–2,而不在 lr–4。

该指令本身为 16 位,因而需要半字加载,请参阅Figure 6.3。

在 ARM 状态下,SVC 编号以 8 位存储,而不是 24 位。

Figure 6.3. Thumb SVC 指令

Example 6.8 演示处理 SVC 异常的 ARM 代码。 通过动态调用 SVC,可以增大 Thumb 状态下可访问的 SVC 编号的范围。

Example 6.8. SVC 处理程序

PRESERVE8

AREA SVC_Area, CODE, READONLY

EXPORT SVC_HandlerIMPORT C_SVC_Handler

T_bit EQU0x20Thumb bit (5) of CPSR/SPSR.

SVC_Handler

STMFD sp!, {r0-r3, r12, lr} Store registers

MOV r1, sp Set pointer to parameters

MRS r0, spsr Get spsr

STMFD sp!, {r0, r3} Store spsr onto stack and another

register to maintain 8-byte-aligned stack

TST r0, #T_bit Occurred in Thumb state?

LDRNEH r0, [lr,#-2] Yes: Load halfword and...

BICNE r0, r0, #0xFF00...extract comment field

LDREQ r0, [lr,#-4] No: Load word and...

BICEQ r0, r0, #0xFF000000...extract comment field

BL C_SVC_Handler Call main part of handler

LDMFD sp!, {r0, r3} Get spsr from stack

MSR SPSR_cxsf, r0 Restore spsr

LDMFD sp!, {r0-r3, r12, pc}^ Restore registers and return

END

确定要调用的 SVC

进入 SVC 处理程序后,必须确定要调用哪个 SVC。 此信息可存储在指令本身的 0-23 位,如Figure 6.4 所示,或将其传递给某个漏空轿整数寄存器,通常为 R0-R3 中的一个。

Figure 6.4. ARM SVC 指令

顶层 SVC 处理程序可以相对于 LR 加载 SVC 指令 请用汇编语言、C/C++ 内联或嵌入式汇编器编写。

处理程序必须首先将导致异常的 SVC 指令加载到寄存器中。 此时,SVC LR 保存 SVC 指令的下一个指令的地址,这样 SVC 加载到了寄存器(本例中为 R0)中,代码如下:

LDR R0, [lr,#-4]

然后,处理程序可检查注释字段位,以决定所需的 *** 作。 通过清除 *** 作码的前八位来提取 SVC 编号:

BIC R0, R0, #0xFF000000

Example 6.9 演示如何用这些指令编写顶层亏告 SVC 处理程序。 有关在 ARM 状态和 Thumb 状态下处理 SVC 指令的处理程序示例,请参阅Example 6.8。

Example 6.9. 顶层 SVC 处理程序

PRESERVE8

AREA TopLevelSVC, CODE, READONLY Name this block of code.

EXPORT SVC_Handler

SVC_Handler

PUSH {R0-R12,lr} Store registers.

LDRR0,[lr,#-4] Calculate address of SVC instruction

and load it into R0.

BICR0,R0,#0xFF000000 Mask off top 8 bits of instruction

to give SVC number.

Use value in R0 to determine which SVC routine to execute.

LDM sp!, {R0-R12,pc}^ Restore registers and return.

END

汇编语言编写的 SVC 处理程序

要调用请求的 SVC 编号的处理程序,最简单的方法是使用跳转表。 如果 R0 包含 SVC 编号,则Example 6.10 中的代码可以插入到Example 6.9 提供的顶层处理程序中,插入位置在 BIC 指令之后。

Example 6.10. SVC 跳转表

AREA SVC_Area, CODE, READONLY

PRESERVE8

IMPORT SVCOutOfRange

IMPORT MaxSVC

CMPR0,#MaxSVC Range check

LDRLS pc, [pc,R0,LSL #2]

B SVCOutOfRange

SVCJumpTable

DCDSVCnum0

DCDSVCnum1

DCD for each of other SVC routines

SVCnum0SVC number 0 code

BEndofSVC

SVCnum1SVC number 1 code

BEndofSVC

Rest of SVC handling code

EndofSVC

END

C 语言和汇编语言编写的 SVC 处理程序

尽管顶层处理程序始终必须用 ARM 汇编语言编写,处理每个 SVC 的例程既可用汇编语言编写,也可用 C 语言编写。有关限制的说明,请参阅在超级用户模式下使用 SVC。

顶层处理程序使用 BL 指令可跳转到相应的 C 函数。 因为 SVC 编号是由汇编例程加载到 R0 中的,所以作为第一个参数传递给 C 函数。 举例来说,函数可以将此参数值用在 switch() 语句中,请参阅Example 6.11。

若要调用此 C 函数,可以向Example 6.9 中 SVC_Handler 例程添加下面的代码行:

BLC_SVC_Handler Call C routine to handle the SVC

Example 6.11. C 函数中的 SVC 处理程序

void C_SVC_handler (unsigned number)

{

switch (number)

{

case 0 : /* SVC number 0 code */

...

break

case 1 : /* SVC number 1 code */

...

break

...

default :/* Unknown SVC - report error */

}

}

超级用户模式堆栈空间可能是有限的,因此要避免使用需要大量堆栈空间的函数。

MOV R1, spSecond parameter to C routine...

...is pointer to register values.

BLC_SVC_Handler Call C routine to handle the SVC.

用 C 语言编写的 SVC 处理程序可以传入和传出值,前提是顶层处理程序将堆栈指针值作为第二个参数(在 R1 中)传递给 C 函数,并且更新 C 函数以访问该值:

void C_SVC_handler(unsigned number, unsigned *reg)

现在,C 函数在主应用程序代码中遇到 SVC 指令时就可访问存储在寄存器中的值了,请参阅 Figure 6.5。 它可从其中读取:

value_in_reg_0 = reg [0]

value_in_reg_1 = reg [1]

value_in_reg_2 = reg [2]

value_in_reg_3 = reg [3]

也可向其中回写:

reg [0] = updated_value_0

reg [1] = updated_value_1

reg [2] = updated_value_2

reg [3] = updated_value_3

这使已更新的值写入到堆栈的相应位置,然后通过顶层处理程序恢复到寄存器中。

Figure 6.5. 访问超级用户模式堆栈

在超级用户模式下使用 SVC

执行 SVC 指令时:

处理器进入超级用户模式。

CPSR 存储到 SVC SPSR 中。

返回地址存储在 SVC LR 中,请参阅处理器对异常的响应。

如果处理器已经处在超级用户模式下,则会损坏 SVC LR 和 SPSR。

如果在超级用户模式下调用 SVC,则必须存储 SVC LR 和 SPSR,以确保 LR 和 SPSR 的原始值不会丢失。 例如,如果某个特定 SVC 编号的处理程序例程调用另一个 SVC,则必须确保该处理程序例程将 SVC LR 和 SPSR 都存储在堆栈中。 这可确保处理程序的每一次调用都保存返回到调用它的 SVC 后面的指令所需要的信息。Example 6.12 演示如何实现这一点。

Example 6.12. SVC 处理程序

AREA SVC_Area, CODE, READONLY

PRESERVE8

EXPORT SVC_Handler

IMPORT C_SVC_Handler

T_bit EQU 0x20

SVC_Handler

PUSH {R0-R3,R12,lr} Store registers.

MOV R1, sp Set pointer to parameters.

MRS R0, SPSR Get SPSR.

PUSH {R0,R3} Store SPSR onto stack and another register to maintain

8-byte-aligned stack. Only required for nested SVCs.

TST R0,#0x20 Occurred in Thumb state?

LDRHNE R0,[lr,#-2] Yes: load halfword and...

BICNER0,R0,#0xFF00...extract comment field.

LDREQR0,[lr,#-4] No: load word and...

BICEQR0,R0,#0xFF000000...extract comment field.

R0 now contains SVC number

R1 now contains pointer to stacked registers

BL C_SVC_HandlerCall C routine to handle the SVC.

POP {R0,R3} Get SPSR from stack.

MSR SPSR_cf, R0 Restore SPSR.

LDM sp!, {R0-R3,R12,pc}^ Restore registers and return.

END

用 C 和 C++ 编写的嵌套 SVC

可用 C 或 C++ 语言编写嵌套的 SVC。 由 ARM 编译器生成的代码根据需要存储和重新加载 lr_SVC。

从应用程序调用 SVC

可用汇编语言或 C/C++ 调用 SVC。

用汇编语言设置所有必需的寄存器值并发出相关的 SVC。 例如:

MOVR0, #65load R0 with the value 65

SVC0x0Call SVC 0x0 with parameter value in R0

几乎像所有的 ARM 指令那样,SVC 指令可被有条件地执行。

在 C/C++ 中,将 SVC 声明为一个 __SVC 函数并调用它。 例如:

__svc(0) void my_svc(int)

.

.

.

my_svc(65)

这确保了 SVC 以内联方式进行编译,无需额外的调用开销,其前提是:

所有参数都只传入 R0-R3

所有结果都只返回到 R0-R3 中。

参数被传递给 SVC,如同 SVC 是一个真正的函数调用。 但是,如果有二到四个返回值,则必须告诉编译器返回值在一个结构中,并使用__value_in_regs 命令。 这是因为基于 struct 值的函数通常被视为一个 void 函数,它的第一个参数必须是存放结果结构的地址。

Example 6.13 和 Example 6.14 演示一个 SVC 处理程序,该处理程序提供 SVC 编号 0x0、0x1、0x2 和 0x3。 SVC 0x0 和 SVC 0x1 都采用两个整数参数并返回一个结果。SVC 0x2 采用四个参数并返回一个结果。SVC 0x3 采用四个参数并返回四个结果。 此示例位于示例目录(...\svc\main.c 和 ...\svc\svc.h)中。

Example 6.13. main.c

#include <stdio.h>

#include "svc.h"

unsigned *svc_vec = (unsigned *)0x08

extern void SVC_Handler(void)

int main( void )

{

int result1, result2

struct four_results res_3

Install_Handler( (unsigned) SVC_Handler, svc_vec )

printf("result1 = multiply_two(2,4) = %d\n", result1 = multiply_two(2,4))

printf("result2 = multiply_two(3,6) = %d\n", result2 = multiply_two(3,6))

printf("add_two( result1, result2 ) = %d\n", add_two( result1, result2 ))

printf("add_multiply_two(2,4,3,6) = %d\n", add_multiply_two(2,4,3,6))

res_3 = many_operations( 12, 4, 3, 1 )

printf("res_3.a = %d\n", res_3.a )

printf("res_3.b = %d\n", res_3.b )

printf("res_3.c = %d\n", res_3.c )

printf("res_3.d = %d\n", res_3.d )

return 0

}

Example 6.14. svc.h

__svc(0) int multiply_two(int, int)

__svc(1) int add_two(int, int)

__svc(2) int add_multiply_two(int, int, int, int)

struct four_results

{

int a

int b

int c

int d

}

__svc(3) __value_in_regs struct four_results

many_operations(int, int, int, int)

从应用程序动态调用 SVC

在某些情况下,需要调用直到运行时才会知道其编号的 SVC。 例如,当有很多相关 *** 作可对同一目标执行,并且每个 *** 作都有自己的 SVC 时,就会发生这种情况。 在这种情况下,前几节中介绍的方法不适用。

对此,有几种解决方法,例如:

通过 SVC 编号构建 SVC 指令,将它存储在某处,然后再执行该指令。

使用通用的 SVC(作为一个额外的参数)将一个代码作为对其参数执行的实际 *** 作。 通用 SVC 对该 *** 作进行解码并予以执行。

第二种机制可使用汇编语言将所需的 *** 作数传递到寄存器(通常为 R0 或 R12)中来实现。 然后可重新编写 SVC 处理程序,对相应寄存器中的值进行处理。

因为有些值必须用注释字段传递给 SVC,所以有可能将这两种方法结合起来使用。

例如, *** 作系统可能会只用一条 SVC 指令和一个寄存器来传递所需的 *** 作数。 这使得其他 SVC 空间可用于应用程序特定的 SVC。 在一个特定的应用程序中,如果从指令提取 *** 作数的开销太大,则可使用这个方法。 ARM 和 Thumb 半主机指令就是这样实现的。

Example 6.15 演示如何使用 __svc 将 C 函数调用映射到半主机调用。 该示例是根据示例目录中的 retarget.c 编写的,该文件路径为...\emb_sw_dev\source\retarget.c。

Example 6.15. 将 C 函数映射到半主机调用

#ifdef __thumb

/* Thumb Semihosting */

#define SemiSVC 0xAB

#else

/* ARM Semihosting */

#define SemiSVC 0x123456

#endif

/* Semihosting call to write a character */

__svc(SemiSVC) void Semihosting(unsigned op, char *c)

#define WriteC(c) Semihosting (0x3,c)

void write_a_character(int ch)

{

char tempch = ch

WriteC( &tempch )

}

编译器含有一个机制,支持使用 R12 来传递所需运算的值。 在 AAPCS 下,R12 为 ip 寄存器,并且专用于函数调用。 其他时间内可将其用作暂存寄存器。 通用 SVC 的参数被传递到 R0-R3 寄存器中,如前面所述,还可以选择在 R0-R3 中返回值,请参阅 从应用程序调用 SVC。 在 R12 中传递的 *** 作数可以是通用 SVC 调用的 SVC 的编号。 但这不是必需的。

Example 6.16 演示使用通用或间接 SVC 的 C 程序段。

Example 6.16. 使用间接 SVC

__svc_indirect(0x80)

unsigned SVC_ManipulateObject(unsigned operationNumber,

unsigned object,unsigned parameter)

unsigned DoSelectedManipulation(unsigned object,

unsigned parameter, unsigned operation)

{ return SVC_ManipulateObject(operation, object, parameter)

}

它生成以下代码:

DoSelectedManipulation

PUSH {R4,lr}

MOV R12,R2

SVC #0x80

POP {R4,pc}

END

还可使用 __svc 机制从 C 中传递 R0 中的 SVC 编号。 例如,如果将 SVC 0x0 用作通用 SVC, *** 作 0 为字符读, *** 作 1 为字符写,则可以进行如下设置:

__svc (0) char __ReadCharacter (unsigned op)

__svc (0) void __WriteCharacter (unsigned op, char c)

可通过如下定义使其具有更好的可读性风格:

#define ReadCharacter () __ReadCharacter (0)

#define WriteCharacter (c) __WriteCharacter (1, c)

但是,如果以这种方式使用 R0,则仅有三个寄存器可用于向 SVC 传递参数。 通常,在不得不将除 R0-R3 之外的更多参数传递给子例程时,可通过使用堆栈来完成 但是,SVC 处理程序不容易访问堆栈参数,因为这些参数通常在用户模式堆栈中,而不是在 SVC 处理程序使用的超级用户模式堆栈中。

作为另一种选择,其中一个寄存器(通常是 R1)可用来指向存储其他参数的内存块。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12211352.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存