我正在嘗試使用 C 中的系統呼叫創建一個通用鏈表,但我不確定從哪里開始。我知道如何撰寫標準鏈表,但不知道如何僅使用系統呼叫來轉換它。例如,如果我們使用malloc()它是一個庫呼叫,那么我不能使用malloc它,因為它不是系統呼叫。
我來自這個網站https://kernelnewbies.org/FAQ/LinkedLists。它提到創建一個內核鏈接串列,但我似乎無法編譯它。
#include <linux/list.h>
struct mystruct
{
int data;
struct list_head mylist;
};
struct mystruct first ={
.data = 10,
.mylist = LIST_HEAD_INIT(first.mylist);
}
得到這個編譯器錯誤說 致命錯誤:linux/list.h:沒有這樣的檔案或目錄
我的標準鏈表:
#include <stdio.h>
#include <stdlib.h>
//Lets create a STRUCT node
struct Node
{
//Any data type since it is a VOID pointer
void *data;
struct Node *next;
};
//Add the Data to the LinkedList
void push(struct Node** head_ref, void *new_data,size_t data_size)
{
//Dynamically allocate the array
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
new_node->data = malloc(data_size);
new_node->next = (*head_ref);
//This will copy the contents of new_dat to newly allocated memory
int i;
for(i=0; i < data_size; i )
{
*(char *)(new_node->data i) = *(char*)(new_data i);
}
//Change head pointer as new node is added at the beginning
(*head_ref) = new_node;
}
void deleteNode(struct Node *head, struct Node *n)
{
// When node to be deleted is head node
if(head == n)
{
if(head->next == NULL)
{
printf("There is only one node. The list can't be made empty ");
return;
}
/* Copy the data of next node to head */
head->data = head->next->data;
// store address of next node
n = head->next;
// Remove the link of next node
head->next = head->next->next;
// free memory
free(n);
return;
}
// When not first node, follow the normal deletion process
// find the previous node
struct Node *prev = head;
while(prev->next != NULL && prev->next != n)
prev = prev->next;
// Check if node really exists in Linked List
if(prev->next == NULL)
{
printf("\n Given node is not present in Linked List");
return;
}
// Remove node from Linked List
prev->next = prev->next->next;
// Free memory
free(n);
return;
}
//Fptr is to access the function to be used for printing current node data
void printList(struct Node *node, void (*fptr)(void *))
{
while(node != NULL)
{
(*fptr)(node->data);
node = node->next;
}
}
//NOTE Different data types need different specifier print command
void printInt(void *n)
{
printf(" %d", *(int *)n);
}
//Function to print a float
void printFloat(void *f)
{
printf(" %f", *(float *)f);
}
int main()
{
//Create an array with the empty data as a start
struct Node *start = NULL;
//Create and print an int linked list
unsigned int_size = sizeof(int);
int arr[] = {10, 20,30,40, 50}, i;
for (i = 4; i >= 0; i--)
{
push(&start, &arr[i], int_size);
}
//You have to tell the position of the data by using the next
deleteNode(start, start->next);
printf("Created integer linked list is \n");
printList(start, printInt);
//Create and print a float linked list;
return 0;
}
所以我的問題是:如何將標準串列轉換為僅使用系統呼叫?
uj5u.com熱心網友回復:
例如,如果我們使用
malloc()它是一個庫呼叫,那么我不能使用malloc它,因為它不是系統呼叫。
然后您可以管理分配在堆疊上的“自己的記憶體”。您的代碼(簡化為僅使用int資料)可能如下所示:
#include <stdio.h>
typedef int NodeRef;
struct Node {
int data;
NodeRef next; // index in memo (array)
};
#define MEMSIZE 1000
#define NULLREF MEMSIZE
NodeRef first_free = 0;
NodeRef unused = 0;
struct Node memo[MEMSIZE];
// Getters and setters:
NodeRef getNext(NodeRef node) {
return memo[node].next;
}
void setNext(NodeRef node, NodeRef next) {
memo[node].next = next;
}
int data(NodeRef node) {
return memo[node].data;
}
void setData(NodeRef node, int data) {
memo[node].data = data;
}
// Allocation / Deallocation
NodeRef newNode(int data, NodeRef next) {
NodeRef node = first_free;
if (node == NULLREF) {
printf("No more memory available for new nodes\n");
} else {
first_free = first_free < unused ? getNext(first_free) : first_free 1;
if (first_free > unused) unused = first_free;
setData(node, data);
setNext(node, next);
}
return node;
}
void discardNode(NodeRef node) {
setNext(node, first_free);
first_free = node;
}
// Linked List actions
void push(NodeRef* head_ref, int new_data) {
NodeRef new_node = newNode(new_data, *head_ref);
if (new_node != NULLREF) {
(*head_ref) = new_node;
}
}
void deleteNode(NodeRef* head_ref, NodeRef node) {
if (*head_ref == NULLREF) {
printf("Cannot delete from an empty Linked List\n");
return;
}
if (*head_ref == node) {
(*head_ref) = getNext(*head_ref);
} else {
NodeRef prev = *head_ref;
while (getNext(prev) != node) {
prev = getNext(prev);
if (prev == NULLREF) {
printf("Given node is not present in Linked List\n");
return;
}
}
setNext(prev, getNext(node));
}
discardNode(node);
}
void printList(NodeRef node) {
while (node != NULLREF) {
printf(" %d", data(node));
node = getNext(node);
}
printf("\n");
}
int main() {
NodeRef start = NULLREF;
int arr[] = {10, 20,30, 40, 50}, i;
for (i = 4; i >= 0; i--) {
push(&start, arr[i]);
}
deleteNode(&start, getNext(start));
printf("Created integer linked list is:\n");
printList(start);
return 0;
}
uj5u.com熱心網友回復:
您可以使用@trincot的方法,但它不會利用系統呼叫。這完全沒問題,如果我沒記錯的話bash是以某種方式實作的,它不需要一個單一的malloc,而是像@trincot建議的那樣。但這里有一個實際系統呼叫的替代方法:
我相信,在匯編程式中可以最好地理解系統呼叫,并且在 Linux 下使用系統呼叫意味著,你寫入EAX你想要的呼叫并執行,然后觸發一個中斷0x80,它命令你的內核執行它。
出于這個原因,系統呼叫依賴于作業系統,簡單地說,所有系統呼叫都是某些內核函式(通常以 為前綴sys_),它們具有明確定義的編號,所有這些通常都可以在/usr/include/bits/syscall.h. 了解這一點很重要,因為標準 C 庫(通常是 glibc)可以malloc在這些系統呼叫之上實作類似的功能。當然,對于每個單獨的標準庫呼叫來說,這并非如此,但這意味著您也可以實作自己的 malloc 函式,并以 glibc、ulibc、dietlibc 為例說明如何實作這一點。
在更高的層次上,您可以使用syscall,它本身就是 glibc 中的一個函式來開始使用。但是為了避免任何此類呼叫,也可以使用-nostdlib引數來編譯您的程式 to gcc。這使得撰寫程式有點困難,因為int main如果你不整理呼叫堆疊,你甚至不能使用函式并且你的程式會崩潰,這是術語argv和argc.
由于我目前正在午休,因此我沒有完整的示例供您參考,但是以下程式可能足以讓您入門
// gcc -o main -nostdlib main.c
#include <sys/syscall.h>
static inline
int syscall(int syscall_number, int arg1, int arg2, int arg3) {
int ret;
asm volatile (
"pushl %
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/480489.html
