<- previous    index    next ->

Lecture 11 Privileged instructions

The Intel 80x86 and beyond have privilege levels.
There are instructions that can only be executed at the highest
privilege level, CPL = 0. This would be reserved for the
operating system in order to prevent the average user from
causing chaos. e.g. The average user could issue a HLT instruction
to halt the machine and thus every process would be dead.
Other CPL=0 only instructions include:
  CLTS  Clear Task Switching flag in cr0
  INVP  Invalidate cache
  INVLPG Invalidate translation lookaside buffer, TLB
  WBINVD Write Back and Invalidate cache

It should be obvious that when running a multiprocessing operating
system, that there are many instructions that only the operating
system should use.

The operating system controls the resources of the computer,
including RAM, I/O and user processes. Some sample protections
are tested by the following sample programs:

A few simple tests to be sure protections are working.
These three programs result in segfault, intentionally.
safe_64.asm store into read only section
; safe_64.asm   for testing protections within sections
; Assemble:	nasm -f elf64  safe_64.asm
; Link:		gcc -o safe_64  safe_64.o
; Run:		./safe_64
; Output:
; it should stop with a system caught error

        global main		; the standard gcc entry point
        extern	printf		; the C function, to be called

        section .rodata		; read only data section, constants
a:	dq	5		; long int a=5;
fmt:    db "Bad, still running",10,0


        section .text           ; Code section. not writeable
main:				; the program label for the entry point
        push    rbp		; set up stack frame

	mov	rax,0x789abcde
	mov	[a],rax		; should be error, read only section  !!!!!!!!!!
        mov	rdi,fmt		; address of format string
	mov	rax,0
	call	printf

        pop     rbp
	mov	rax,0		; normal, no error, return value
	ret			; return
	

safe1_64.asm store into code section
; safe_64.asm   for testing protections within sections
; Assemble:	nasm -f elf64   safe1_64.asm
; Link:		gcc -o safe1_64  safe1_64.o
; Run:		./safe1_64
; Output:
; it should stop with a system caught error

        global main		; the standard gcc entry point
        extern	printf		; the C function, to be called

        section .rodata		; read only data section, constants
a:	dq	5		; long int a=5;
fmt:    db "Bad, still running",10,0


        section .text           ; Code section. not writeable
main:				; the program label for the entry point
        push    rbp		; set up stack frame

	mov	rax,0x789abcde
	mov	[main],rax	; should be error, can not change code .text !!!!!!
        mov	rdi,fmt		; address of format string
	mov	rax,0
	call	printf

        pop     rbp
	mov	rax,0		; normal, no error, return value
	ret			; return
	

safe2_64.asm jump (execute) data
; safe2_64.asm   for testing protections within sections
; Assemble:	nasm -f elf64  safe2_64.asm
; Link:		gcc -o safe2_64  safe2_64.o
; Run:		./safe2_64
; Output:
; it should stop with a system caught error

        global main		; the standard gcc entry point
        extern	printf		; the C function, to be called

        section .rodata		; read only data section, constants
a:	dq	5		; long int a=5;
fmt:    db "Bad, still running",10,0


        section .text           ; Code section. not writeable
main:				; the program label for the entry point
        push    rbp		; set up stack frame

	mov	rax,0x789abcde
	jmp	a		; should be error, can not execute data !!!!!!!!
        mov	rdi,fmt		; address of format string
	mov	rax,0
	call	printf

        pop     rbp
	mov	rax,0		; normal, no error, return value
	ret			; return
	

A few simple tests to be sure privileged instructions can not execute.
priv_64.asm hlt instruction to halt computer
; priv_64.asm   for testing that average user
;               can not execute privileged instructions 
; Assemble:	nasm -f elf64 priv_64.asm
; Link:		gcc -o priv_64  priv_64.o
; Run:		./priv_64
; Output:
; it should stop with a system caught error

        global main		; the standard gcc entry point
        extern	printf		; the C function, to be called
fmt:    db "bad! Still running",10,0	; The printf format, "\n",'0'


        section .text           ; try to halt the computer
main:				; the program label for the entry point
        push    rbp		; set up stack frame

	hlt			; should be error, only allowed in CPL=0  !!!!!!!

        mov	rdi,fmt		; address of format string
	mov	rax,0
	call	printf

        pop     rbp
	mov	rax,0		; normal, no error, return value
	ret			; return
	

	

priv1_64.asm other privileged instructions
; priv1_64.asm   for testing that average user
;                can not execute privileged instructions 
; Assemble:	nasm -f elf64 priv1_64.asm
; Link:		gcc -o priv1_64  priv1_64.o
; Run:		./priv1_64
; Output:
; it should stop with a system caught error

        global main		; the standard gcc entry point
        extern	printf		; the C function, to be called
fmt:    db "bad! Still running",10,0	; The printf format, "\n",'0'


        section .text           ; try to halt the computer
main:				; the program label for the entry point
        push    rbp		; set up stack frame

	clts			; should be error, only allowed in CPL=0  !!!!!!!
        wbinvd			; never gets to these, also error

	
        mov	rdi,fmt		; address of format string
	mov	rax,0
	call	printf

        pop     rbp
	mov	rax,0		; normal, no error, return value
	ret			; return
	

	

In order to allow the user some access, controlled access, to
system resources, an interface to the operating system, or kernel,
is provided. You will see in the next lecture that some BIOS
functions are also provided as Linux kernel calls.



To implement list in NASMlist_64.c
Here is some sample code related to first "push"

; test_alist_64.asm  generating test data in heap and list
;	           (some  list_64.c  included as comments)

	extern	printf

; static char heap[20000] 	; space to store strings, do not reuse or free
; static char *hp = heap;	; pointer to next available heap space         
; static long int  list[1000];	; space to store list block (2 index+ pointer) 
; static long int  lp=1; 	; index to next available list space
; static char *q;    		; q, a pointer to a character
; static long int i;  		; a variable index
	section .bss
heap:	resb	20000		; could be gigabytes
list:	resq	1000		; could be millions
q:	resq	1		; may be just in  rsi
i:	resq	1		; may be just in  rdi
		
	section	.data
hp:	dq	heap		; [hp] is pointer to next free heap
lp:	dq	1		; index of next available list item
test:	db "middle",0, "last",0, "front",0 ; just using middle

	
fmt1:	db	"%s",10,0  ; "%s\n" for printf
fmtend:	db	10,0	   ; "\n" 

;   push_back "middle", push_back "last", push_front "front" 
;        +-----------------+   +-----------------+   +-----------------+
; L[0]-> |  index to next----->|  index to next----->|  0              |
;        |  0              |<-----index to prev  |<-----index to prev  |<-L[1]
;        | ptr to heap str |   | ptr to heap str |   | ptr to heap str |
;        +-----------------+   +-----------------+   +-----------------+
; The pointers to heap strings are character pointers to terminated strings.
; The "index" values could be pointers rather than indices.

	global main
main:
        push	rbp		; save rbp, no registers need saving
;set up test for the first push into the list

	mov	rax,1		; initial list index (*8 for address)
	mov	qword [list+8*rax],0      ; list[1]=0 no more
	mov	qword [list+8*(rax+1)],0  ; list[2]=0 no more
	mov	rbx,[hp]		    ; string address in heap
	mov	[list+8*(rax+2)],rbx ; list[3] = string address in heap
				; set L[0] = 1 = rax this is first push
				; set L[1] = 1 = rax
	mov	rbx, 0		; clear rbx, we use bl for byte
	mov	rsi, test	; similar to a push_front call
	mov	rax, [hp]	; address of heap in rax
move:	mov	bl, [rsi]	; picks up a character from test
	mov	[rax], bl	; put character on heap
	inc	rsi		; increment from address, user
	inc	rax		; increment to address, heap
	cmp	bl, 0
	jne	move
	mov	[hp],rax	; next available heap address saved

	mov	rdi, fmt1
	mov	rsi, heap
	mov	rax, 0
	call	printf

	pop	rbp
	mov	rax, 0
        ret			; return

Questions?
Help with Project ?

    <- previous    index    next ->

Other links

Go to top