Saving registers

All interrupt handlers need to save the general purpose CPU registers on the stack. The macro shown Figure 10.15, from entry.S, does that.

85

#define SAVE_ALL

\

86

cld;

\

87

pushl %es;

\

88

pushl %ds;

\

89

pushl %eax

\

90

pushl %ebp

\

91

pushl %edi

\

92

pushl %esi

\

93

pushl %edx

\

94

pushl %ecx

\

95

pushl %ebx

\

96

movl $(_KERNEL_DS),%edx;

\

97

movl%edx,%ds;

\

98

movl%edx,?

ies;

Figure 10.15 Macro to save registers

Figure 10.15 Macro to save registers

86 This clears the direction flag bit in EFLAGS to 0. After this, string instructions will increment the index registers ESI and EDI (as opposed to decrementing them).

87-95 the registers are pushed one by one. The order conforms to that in a struct pt_regs. Note that the values on the stack before SAVE_ALL is called constitute the remainder of the structure. The whole stack frame is frequently referenced as a struct pt_regs. Also note that in reverse order the last three are EBX, ECX, and EDX. These contain parameters (if any) for the handler function being called to service the exception.

96-98 the data segment register (DS) and the extra segment register (ES) are set to point to the kernel data segment. This may seem a roundabout way of doing things, but the segment registers cannot be loaded directly; they can only be loaded from another register. We are, after all, about to execute kernel code, so it is logical that we should be using the kernel data segment.

Continue reading here: The Linux system call entry

Was this article helpful?

0 0