Übung 5
This commit is contained in:
105
Assets/Betriebssysteme_uebung/u6-a1-anlage/syscall.c
Normal file
105
Assets/Betriebssysteme_uebung/u6-a1-anlage/syscall.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/* syscall.c
|
||||
*
|
||||
* Call OS functions without using libc. The example `my_print` could be done in
|
||||
* different flavors:
|
||||
*
|
||||
* **my_print_64:**
|
||||
* Using the SYSCALL instruction (successor to SYSENTER). Should work for both
|
||||
* IA-64 and AMD64 CPUs, can be ported to `my_print_trap` (see there).
|
||||
* Register usage:
|
||||
*
|
||||
* - RAX: pass syscall number, hold return value from syscall execution
|
||||
* - RDI: syscall argument 1
|
||||
* - RSI: syscall argument 2
|
||||
* - RDX: syscall argument 3
|
||||
*
|
||||
* **my_print_trap:**
|
||||
* Using the trap interrupt to switch to kernel mode. Slower, but
|
||||
* architecturally neutral. Register usage:
|
||||
*
|
||||
* - EAX: pass syscall number, hold return value from syscall execution
|
||||
* - EBX: syscall argument 1
|
||||
* - ECX: syscall argument 2
|
||||
* - EDX: syscall argument 3
|
||||
*/
|
||||
|
||||
#include <asm/unistd.h> /* compile with -m32 for 32-bit syscall numbers,
|
||||
without for 64-bit syscall numbers. */
|
||||
/* simple inline assembler (asm) requires global symbols */
|
||||
#define __NR_exit 60
|
||||
// text buffer pointer
|
||||
char *my_print_text;
|
||||
// text buffer length, print return value
|
||||
int my_print_len, my_print_ret;
|
||||
// write() syscall number
|
||||
int call_write;
|
||||
int exitnum;
|
||||
|
||||
int my_print_64(char *text) {
|
||||
my_print_text = text;
|
||||
|
||||
/* strlen(my_print_text) manually */
|
||||
for (my_print_len = 0; my_print_text[my_print_len]; ++my_print_len);
|
||||
|
||||
/* system call signature:
|
||||
* ssize_t write(int fd, const void *buf, size_t count);
|
||||
*
|
||||
* write() system call number is defined by __NR_write
|
||||
*/
|
||||
call_write = __NR_write;
|
||||
/* stdout is file descriptor no. 1 */
|
||||
asm("mov call_write, %rax"); /* arg 0 (rax): syscall number */
|
||||
asm("mov $1, %rdi"); /* arg 1 (rdi): file descriptor */
|
||||
asm("mov my_print_text, %rsi"); /* arg 2 (rsi): buffer */
|
||||
asm("mov my_print_len, %rdx"); /* arg 3 (rdx): length */
|
||||
asm("syscall"); /* SYSCALL instruction */
|
||||
asm("mov %rax, my_print_ret"); /* save return code (rax) */
|
||||
|
||||
return my_print_ret;
|
||||
}
|
||||
|
||||
int my_print_trap(char *text) {
|
||||
/* system call signature: see my_print_64 */
|
||||
|
||||
/* TODO */
|
||||
|
||||
return 7;
|
||||
}
|
||||
|
||||
/* simple inline assembler (asm) requires global symbols */
|
||||
|
||||
// exit return value
|
||||
int my_exit_status;
|
||||
|
||||
void my_exit_64(int status) {
|
||||
my_exit_status = status;
|
||||
|
||||
/* system call signature:
|
||||
* void exit(int status);
|
||||
*
|
||||
* exit() system call number is defined by __NR_exit
|
||||
*/
|
||||
|
||||
/* TODO */
|
||||
// Syscall
|
||||
//exitnum = __NR_exit;
|
||||
//asm("mov $60, %rax"); // verwende den exitnum / 60 Syscall
|
||||
//asm("mov my_exit_status, %rdi"); //status = myexitstatus oder 0
|
||||
//asm("syscall");
|
||||
//TRAP
|
||||
asm("mov $1, %eax");
|
||||
asm("mov my_exit_status, %ebx");
|
||||
asm("int $0x80");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
my_print_64("Hello World!\n");
|
||||
|
||||
my_exit_64(42);
|
||||
|
||||
/* never come here, if my_exit_64 works */
|
||||
return 6;
|
||||
}
|
||||
Reference in New Issue
Block a user