cuốn sách gpt4 ai đã làm

Kiến trúc máy ảo tuyệt vời-AQ

In lại Tác giả: Sahara Thời gian cập nhật: 2024-07-20 12:58:41 58 4
mua khóa gpt4 Nike

Liên kết nguồn: https://www.axa6.com/zh/an-excellent-virtual-machine-memory-architecture.

Giới thiệu

Kiến trúc bộ nhớ máy ảo ảnh hưởng trực tiếp đến hiệu suất và khả năng chiếm dụng của máy ảo. Thiết kế một kiến trúc xuất sắc có thể cải thiện hiệu suất và hiệu quả một cách hiệu quả. Bài viết này sẽ giới thiệu kiến trúc bộ nhớ được sử dụng bởi máy ảo AQ và các tiêu chuẩn chi tiết về bộ nhớ máy ảo AQ. Bằng cách tối ưu hóa kiến trúc bộ nhớ máy ảo, nó giúp máy ảo chạy hiệu quả hơn và giảm chiếm dụng. Nếu có thể, bạn nên cân bằng cả hai càng nhiều càng tốt để máy ảo của bạn đạt được hiệu suất tốt nhất.

Trong một số trường hợp, việc phát triển phải được thực hiện khác nhau tùy theo nhu cầu đặc biệt của máy ảo. Ví dụ: Trong trường hợp bộ nhớ hạn chế như vi điều khiển, cần giảm chiếm dụng càng nhiều càng tốt. Trong các tình huống nhạy cảm về hiệu suất như tính toán song song, bạn cần tập trung vào việc tối ưu hóa hiệu suất.

ý tưởng thiết kế

kiến trúc bộ nhớ

Kiến trúc bộ nhớ cơ bản

AQ áp dụng kiến trúc bộ nhớ cơ bản của các thanh ghi, nhưng nó khác với kiến trúc thanh ghi tiêu chuẩn và đã thực hiện một số cải tiến và tối ưu hóa đối với kiến trúc thanh ghi.

Các thanh ghi ở đây không phải là các thanh ghi trong CPU mà là các thanh ghi ảo được mô phỏng trong bộ nhớ.

Lý do chọn đăng ký

So với các máy ảo ngôn ngữ chính thống như JAVA và Python, sử dụng kiến trúc ngăn xếp, lý do AQ quyết định áp dụng kiến trúc đăng ký là để tối ưu hóa hiệu suất và làm cho mã byte dễ hiểu hơn. Mặc dù kiến trúc ngăn xếp thường được coi là dễ chuyển và ghi hơn, nhưng sẽ có một số tổn thất về hiệu suất thực tế và việc truy cập nhiều lần vào bộ nhớ sẽ làm chậm nó, điều này là không thể tránh khỏi và khó tối ưu hóa hoàn toàn. Do đó, để giải quyết tình trạng giảm hiệu suất ở đây, AQ áp dụng kiến trúc đăng ký. Đồng thời, từ góc độ mã byte, mã byte của kiến trúc thanh ghi dễ hiểu hơn và các hướng dẫn của nó tương tự như phương thức tham số của hàm, thay vì trực tiếp đối mặt với nhiều thao tác của ngăn xếp.

đăng kýSự khác biệt về kiến trúc

Kiến trúc thanh ghi tiêu chuẩn

Trong kiến trúc thanh ghi tiêu chuẩn, các thanh ghi bao gồm:

  1. kiểu dữ liệu - Kiểu dữ liệu mà thanh ghi sẽ lưu trữ (chẳng hạn như int, float, double, v.v.)
  2. dữ liệu - Giá trị của dữ liệu mà thanh ghi sẽ lưu trữ
  3. (tùy chọn) thẻ - Thẻ cho dữ liệu mà thanh ghi sẽ lưu trữ (ví dụ: biến, hàm, lớp, v.v.)
  4. (tùy chọn) tham chiếu - tham chiếu đến dữ liệu mà thanh ghi sẽ lưu trữ (chẳng hạn như địa chỉ của một đối tượng, v.v.)

Mặc dù kiến trúc bộ nhớ của máy ảo ở các ngôn ngữ khác nhau có thể khác nhau nhưng thông tin này thường được lưu trữ.

Kiến trúc này đã được sử dụng trong quá trình phát triển AQ, nhưng sau khi thử nghiệm, nó chiếm một lượng lớn bộ nhớ.

Sau đây là mã register.h được AQ sử dụng:

// Bản quyền của tác giả AQ 2024, Mọi quyền được bảo lưu. // Chương trình này được cấp phép theo Giấy phép AQ. Bạn có thể tìm thấy giấy phép AQ trong // thư mục gốc. { // VIỆC CẦN LÀM(Đăng ký): Đang chờ sự cải thiện của sổ đăng ký. sự đoàn kết AqvmMemoryRegister_Value { // TODO(Register): Đang chờ cải thiện thanh ghi. const int int_value; const int const_int_value; const float const_float_value; const double long_value; const_character_value; boolean_value; const bool const_boolean_value }; struct AqvmMemoryRegister_Register { enum AqvmMemoryRegister_ValueType; liên kết giá trị AqvmMemoryRegister_Value };

Như có thể thấy từ đoạn mã trên, ngay cả khi chỉ giữ lại nội dung cần thiết, vì kiểu enum AqvmMemoryRegister_ValueType chiếm 4 byte và kiểu kết hợp AqvmMemoryRegister_Value chiếm 8 byte, nên bản thân kiểu cấu trúc sẽ chiếm 12 byte bộ nhớ.

Đồng thời, do tối ưu hóa trình biên dịch C, kiểu enum trong kiểu cấu trúc AqvmMemoryRegister_Register là bộ nhớ được căn chỉnh theo giá trị kiểu kết hợp, do đó 4 byte bộ nhớ đệm được thêm vào. Đặt AqvmMemoryRegister_Register thuộc loại cấu trúc chiếm 16 byte.

Nếu bạn sử dụng loại không phải 8 byte như int, 4 byte bộ nhớ đệm sẽ bị lãng phí, dẫn đến mất bộ nhớ. Vì vậy sẽ có 4-8 byte bộ nhớ bị lãng phí trong tất cả các thanh ghi.

AQCấu trúc thanh ghi của

Để giải quyết vấn đề chiếm chỗ của kiến trúc thanh ghi truyền thống, AQ kết hợp các đặc điểm bảng biến cục bộ của khung ngăn xếp JVM và tối ưu hóa kiến trúc bộ nhớ, giảm đáng kể vấn đề chiếm chỗ.

Sau đây là ba lựa chọn thay thế:

// kế hoạch 1: struct AqvmMemoryRegister_Register{ uint8_t type; void* value_ptr; }; void* value; AqvmMemoryRegister_Register array[]; // kế hoạch 2: giá trị void*; 0 cho chỉ số 1 là // float, v.v. size_t type[] // plan 3: struct AqvmMemoryRegister_Register { giá trị uint32_t*; kích thước size_t };

Do con trỏ chiếm 4-8 byte nên bản thân dữ liệu cũng chiếm 1-8 byte, cộng với byte loại 1 nên phương án 1 chiếm 6-17 byte và có thể có sự căn chỉnh bộ nhớ nên phương án 1 cũng sẽ gây ra sự mất bộ nhớ rất lớn. . Trên thực tế, khi cần lưu giữ thông tin loại bộ nhớ, gói 2 có mức sử dụng bộ nhớ cao nhất, nhưng gói 2 không thể duy trì sự gắn kết của các loại dữ liệu khác nhau trong cùng một cấu trúc dữ liệu (chẳng hạn như cấu trúc), điều này có thể làm mất hiệu lực một số con trỏ. hoạt động. Do đó, kế hoạch 2 không được sử dụng để đảm bảo an toàn cho bộ nhớ. Trong một số trường hợp (tập lệnh máy ảo bao gồm các loại), phương án 3 cũng có thể đáp ứng nhu cầu lưu trữ bộ nhớ, nhưng do nhu cầu tập lệnh rút gọn nên thông tin loại không có trong hướng dẫn nên không thể đáp ứng được nhu cầu. hoạt động của máy ảo.

Do đó, chúng tôi áp dụng thiết kế sau để đảm bảo sử dụng bộ nhớ và cải thiện đáng kể vấn đề sử dụng bộ nhớ.

Bộ nhớ của AQ trực tiếp sử dụng con trỏ void* để lưu trữ dữ liệu, bộ lưu trữ size_t chiếm kích thước bộ nhớ và sử dụng kiểu lưu trữ mảng uint8_t. Vì uint8_t chiếm 8 bit nên để giảm dung lượng chiếm chỗ, 4 bit được sử dụng cho mỗi byte để lưu trữ loại. Do đó, một biến uint8_t có thể lưu trữ 2 loại. 4 bit đầu tiên của mỗi biến uint8_t được sử dụng cho loại byte chẵn và 4 bit cuối cùng được sử dụng cho loại byte lẻ.

// Cấu trúc lưu trữ thông tin về bộ nhớ. // |type| là một con trỏ tới một mảng lưu trữ kiểu của mỗi byte trong bộ nhớ //. Mỗi byte sử dụng 4 bit để lưu trữ kiểu này. / lưu trữ 2 loại. 4 bit đầu tiên của biến uint8_t được sử dụng cho loại byte chẵn và 4 bit tiếp theo được sử dụng cho loại byte lẻ. |data| là một con trỏ kiểu void* tới bộ nhớ lưu trữ dữ liệu // |size| là kích thước của bộ nhớ. // LƯU Ý: Cấu trúc AqvmMemory_Memory chỉ lưu trữ thông tin của bộ nhớ. bởi hàm bytecode khi lưu trữ bytecode. // Bộ nhớ của |memory| và |type| là một phần của dữ liệu bytecode struct AqvmMemory_Memory { uint8_t* void*; kích thước size_t;

Vì lý do bộ nhớ, việc truy cập kiểu yêu cầu sử dụng chính xác. Loại uint8_t yêu cầu 8 bit, nhưng nó vượt quá nhu cầu lưu trữ của loại, vì vậy 4 bit không chỉ có thể đáp ứng nhu cầu lưu trữ của loại mà còn giảm mức sử dụng bộ nhớ. Nhưng cần có các chức năng đặc biệt để duy trì quyền truy cập kiểu.

// Đặt loại dữ liệu tại |index| byte trong |memory| thành |type|. // phải nhỏ hơn 4 bit. Trả về 0 nếu thành công. . Trả về -2 // nếu con trỏ kiểu là NULL. Trả về -3 nếu chỉ mục nằm ngoài phạm vi. Trả về // -4 nếu kiểu nằm ngoài phạm vi. Bộ nhớ AqvmMemory_Memory*, chỉ mục size_t, loại uint8_t) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL); trả về -1; } nếu (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullTypePointer\"", "\"Con trỏ loại là NULL.\"", NULL return -2 }; (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_SetType_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL); return -3; } if (type > 0x0F) { AqvmRuntimewindow_OutputReport("\ "LỖI\"", "\"AqvmMemory_SetType_OutOfTypeRange\"", "\"Loại nằm ngoài phạm vi.\"", NULL); return -4; } // Đặt loại dữ liệu tại |index| byte trong bộ nhớ. // Vì Aqvm lưu trữ dữ liệu loại chiếm 4 bit và uint8_t. chiếm 8 bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu. // (4 bit cao, 4 bit thấp) được đặt theo tính chẵn lẻ của |index|. các bit cao của (|index| / 2) và số lẻ được // lưu trữ trong các bit thấp của (|index| / 2). = (bộ nhớ->loại [chỉ mục / 2] & 0xF0) | loại; } else { bộ nhớ->loại [chỉ mục / 2] = (bộ nhớ->loại [chỉ mục / 2] & 0x0F) | (type << 4); } return 0; } // Lấy loại dữ liệu tại |index| byte trong |memory|. // Trả về loại nhỏ hơn 4 bit (0X0F) nếu thành công. / nếu con trỏ bộ nhớ là NULL. Trả về 0x12 nếu con trỏ loại là NULL // Trả về 0x13 nếu chỉ mục nằm ngoài phạm vi bộ nhớ uint8_t. AqvmMemory_GetType(struct AqvmMemory_Memory* bộ nhớ, chỉ mục size_t) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL); trả về 0x11 } nếu (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullTypePointer\"", "\"Con trỏ loại là NULL.\"", NULL trả về 0x12; chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_GetType_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"",NULL); return 0x13; } // Lấy loại dữ liệu tại |index| byte trong bộ nhớ // Vì Aqvm lưu trữ loại dữ liệu chiếm 4 bit và uint8_t chiếm 8 bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu. Các vị trí lưu trữ // (4 bit cao, 4 bit thấp) được đặt theo tính chẵn lẻ của |index|. 2) và các số lẻ được // lưu trữ ở các bit thấp của (|index| / 2). if (index % 2 != 0) { return Memory->type[index / 2] & 0x0F; bộ nhớ->loại [chỉ mục / 2] & 0xF0) >> 4;

Tuy nhiên, sử dụng thiết kế này có yêu cầu cao hơn về việc lưu trữ dữ liệu, do độ dài của dữ liệu không cố định nên cần có các chức năng đặc biệt để hoạt động với bộ nhớ.

// Ghi dữ liệu |data_ptr| trỏ đến có kích thước |size| vào dữ liệu tại // |index| byte trong |memory|. // Trả về 0 nếu thành công. -2 // nếu con trỏ kiểu là NULL. Trả về -3 nếu chỉ mục nằm ngoài phạm vi. Trả về // -4 nếu con trỏ dữ liệu là NULL. Bộ nhớ AqvmMemory_Memory*, chỉ mục size_t, void* data_ptr, size_t size) { if (memory == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL. \"", NULL); trả về -1 } nếu (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_WriteData_NullTypePointer\"", "\"Con trỏ loại là NULL.\"", NULL trả về -2 }; (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL); return -3; } if (data_ptr == NULL) { AqvmRuntimewindow_OutputReport(" \"LỖI\"", "\"AqvmMemory_WriteData_NullDataPointer\"", "\"Con trỏ dữ liệu là NULL.\"", NULL); return -4; } // Vì void* không có kích thước cụ thể nên việc di chuyển con trỏ cần phải được // chuyển đổi trước đó di chuyển. memcpy((void*)((uintptr_t)memory->data + index), data_ptr, size return 0;

Ngoài việc giảm mức sử dụng bộ nhớ, điều quan trọng không kém là tránh chiếm dụng bộ nhớ thứ cấp. Do đó, chúng tôi sử dụng lại bộ nhớ của bytecode, lưu trữ dữ liệu bộ nhớ và các loại trong phần bộ nhớ của bytecode và sử dụng bộ nhớ được cấp phát trước trong tệp bytecode (tệp bytecode chứa dữ liệu và loại của bộ nhớ) để triển khai Để sử dụng bộ nhớ hiệu quả. Bởi vì nếu bạn lưu trữ hai phần riêng biệt, bạn cần có hai phần dữ liệu và loại bộ nhớ lặp lại. Một phần nằm trong phần bộ nhớ và phần còn lại, phần mã byte, sẽ không được sử dụng. để giảm thiểu Loại bỏ lãng phí bộ nhớ do dữ liệu và loại bộ nhớ gây ra. Tuy nhiên, việc triển khai chức năng đặc biệt là cần thiết và cần lưu ý rằng việc phân bổ và giải phóng dữ liệu bộ nhớ cũng như các loại bộ nhớ được quản lý bởi các chức năng liên quan đến mã byte.

// Hàm sẽ phân tích cấu trúc AqvmMemory_Memory và sao chép |data|, // |type| và |size| tới cấu trúc nếu // thành công. Trả về NULL nếu việc tạo struct AqvmMemory_Memory* AqvmMemory_CreateMemory(void* data, type void*, size size_t) { struct AqvmMemory_Memory* Memory_ptr = (struct AqvmMemory_Memory*)malloc(sizeof(struct AqvmMemory_Memory)); if (memory_ptr == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_CreateMemory_MemoryAllocationFailure\"", "\"Không thể cung cấp bộ nhớ.\"", NULL); trả về NULL } bộ nhớ_ptr->data = bộ nhớ_ptr->type = bộ nhớ_ptr->size = kích size; } // Giải thích bộ nhớ của |memory_ptr|. // Ý: Hàm giải phóng cấu trúc bộ nhớ chỉ. được con trỏ tới // bởi các con trỏ tới dữ liệu và nhập vào cấu hình không được giải phóng. các hàm liên kết đến byte mã hóa.

Ngoài ra, hãy xác định loại trong một số hệ thống khác với AQ tiêu chuẩn để thiết kế các chức năng liên kết Nếu hệ thống khác với tiêu chuẩn thì phải thiết kế đặc biệt cho hệ thống this system.

// Trả về số lượng cảnh báo. int AqvmMemory_CheckMemoryConditions() { int Warning_count = 0; != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", " \"AqvmMemory_CheckMemoryConditions_IntLengthWarning\"", "\"Yêu cầu về độ dài cho kiểu int không thêm theo định nghĩa " "type " ", NULL); ++warning_count; } if (sizeof(aqlong) != 8) { AqvmRuntimewindow_OutputReport( "\" WARNING\"", "\"AqvmMemory_CheckMemoryConditions_LongLengthWarning\"", "\"Yêu cầu về độ dài cho loại dài không theo định nghĩa " ", NULL); ++warning_count; } if (sizeof(aqfloat) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\" AqvmMemory_CheckMemoryConditions_FloatLengthWarning\"", "\"Yêu cầu về độ dài cho loại float không kèm theo " " định nghĩa loại.\"", NULL); ++warning_count } if (sizeof(aqdouble) != 4) { AqvmRuntimewindow_OutputReport( "\"CẢNH BÁO\"", "\"AqvmMemory_CheckMemoryConditions_DoubleLengthWarning\"", "\"Yêu cầu về độ dài cho loại kép không kèm theo định nghĩa loại " ".\"", NULL); ++warning_count; } if (sizeof(aqchar) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_CharLengthWarning\"", "\"Yêu cầu về độ dài cho loại char không. thủ theo định nghĩa " "type " ".\", NULL); ++warning_count; } if (sizeof(aqbool) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_BoolLengthWarning\"" , "Yêu cầu về độ dài cho loại bool không phù hợp với loại " " định nghĩa.", NULL); ++warning_count; } if (warning_count == 0) { AqvmRuntimewindow_OutputReport("\"INFO\"", "\"AqvmMemory_CheckMemoryConditions_CheckNormal\"", "\"Không có cảnh báo điều kiện bộ nhớ.\"", NULL } return Warning_count }

Chi tiết tiêu chuẩn:

Cấu trúc thư mục

Mã cho bộ nhớ nằm trong /aqvm/memory. Chứa nhiều mã hóa tập tin.

  1. CMakeLists.txt - File build CMake in this folder
  2. bộ nhớ.h - Bộ nhớ cấu trúc và các liên kết chức năng
  3. bộ nhớ.c - Thực hiện các chức năng liên quan đến bộ nhớ
  4. loại.h - Định nghĩa các loại bộ nhớ

bộ nhớ.h

AqvmMemory_Memory

|type| là một con trỏ tới một kiểu lưu trữ từng byte trong bộ nhớ. byte sử dụng 4 bit để lưu trữ loại. Do đó, một biến uint8_t có thể lưu trữ 2 loại. Danh sách các loại có trong type.h. |data| là một kẻ lừa đảo con trỏ void* tới bộ nhớ nơi lưu trữ dữ liệu |size| là kích thước của bộ nhớ. |bộ nhớ| và | bộ nhớ là một phần của bộ nhớ nhớ byte mã hóa.

struct AqvmMemory_Memory { uint8_t* data size void*;

AqvmMemory_CheckMemoryĐiều kiện

Kiểm tra bộ nhớ điều kiện trong hệ thống. Trả về cảnh báo số lượng.

int AqvmMemory_CheckMemoryConditions() { int Warning_count = 0; if (sizeof(aqint) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_IntLengthWarning\"", "\"Yêu cầu độ dài cho kiểu int không phù hợp với " "loại" "định nghĩa.\"", NULL); ++warning_count; } if (sizeof(aqlong) != 8) { AqvmRuntimewindow_OutputReport( "\"WARNING\"" , "\"AqvmMemory_CheckMemoryConditions_LongLengthWarning\"", "\"Yêu cầu về độ dài đối với loại dài không cộng theo định nghĩa " " loại " ".\"", NULL); ++warning_count; } if (sizeof(aqfloat) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_FloatLengthWarning\"", "\" thủ thuật tới " " định nghĩa kiểu.\"", NULL); } if (sizeof(aqdouble) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_DoubleLengthWarning\"", "\"Yêu } if (sizeof(aqchar) != 1) { AqvmRuntimewindow_OutputReport( "\"CẢNH BÁO\"", "\"AqvmMemory_CheckMemoryConditions_CharLengthWarning\"", "\"Yêu cầu về độ dài cho loại char không cộng theo định nghĩa " "type " ".\"", NULL ); ++warning_count } if (sizeof(aqbool) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_BoolLengthWarning\"", "Yêu cầu về độ dài cho loại bool không bổ sung theo loại " " định nghĩa.", NULL); = 0) { AqvmRuntimewindow_OutputReport("\"INFO\"", "\"AqvmMemory_CheckMemoryConditions_CheckNormal\"", "\"Không có cảnh báo điều kiện nhớ.\"", NULL } return Cảnh báo_count }

AqvmMemory_TạoBộ nhớ

Tạo cấu trúc AqvmMemory_Memory chứa |data|, |type| và |size|. Hàm này phân bổ cấu trúc AqvmMemory_Memory và sao chép |data|, |type| và |size| vào cấu trúc đó. Trả về một con trỏ tới cấu trúc này. Trả về NULL nếu việc tạo không thành công.

struct AqvmMemory_Memory* AqvmMemory_CreateMemory(void* data, void* type, size_t size) { struct AqvmMemory_Memory* Memory_ptr = (struct AqvmMemory_Memory*)malloc(sizeof(struct AqvmMemory_Memory)); if (memory_ptr == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_CreateMemory_MemoryAllocationFailure\"", "\"Không thể cấp phát bộ nhớ.\"", NULL trả về NULL } Memory_ptr->data = data; ; bộ nhớ_ptr->size = kích thước trả về bộ nhớ_ptr }

AqvmMemory_FreeMemory

Giải phóng bộ nhớ của |memory_ptr|. Không có giá trị trả lại. Lưu ý: Chức năng này chỉ giải phóng bộ nhớ của cấu trúc. Bộ nhớ được trỏ tới bởi con trỏ tới dữ liệu và kiểu trong cấu trúc sẽ không được giải phóng. Những bộ nhớ này được quản lý bởi các hàm liên quan đến mã byte.

void AqvmMemory_FreeMemory(struct AqvmMemory_Memory* Memory_ptr) { free(memory_ptr }

AqvmMemory_SetType

Đặt kiểu dữ liệu ở byte |index| trong |memory| thành |type|. |loại| phải ít hơn 4 chữ số. Trả về 0 khi thành công. Nếu con trỏ bộ nhớ là NULL, -1 được trả về. Nếu con trỏ chỉ mục là NULL, -2 được trả về. Nếu chỉ số nằm ngoài phạm vi, -3 sẽ được trả về. Nếu loại nằm ngoài phạm vi, -4 sẽ được trả về.

int AqvmMemory_SetType(const struct Bộ nhớ AqvmMemory_Memory*, size_t index, uint8_t type) { if (memory == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL); trả về -1; } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullTypePointer\"", "\"Con trỏ kiểu là NULL.\"", NULL); trả về -2 } if (chỉ mục> bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_SetType_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL return -3; "\"LỖI\"", "\"AqvmMemory_SetType_OutOfTypeRange\"", "\"Loại nằm ngoài phạm vi.\"", NULL); return -4; } // Đặt loại dữ liệu tại |index| lưu trữ dữ liệu loại chiếm 4 bit và uint8_t chiếm 8 bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu Vị trí lưu trữ // (4 bit cao, thấp. 4 bit) được thiết lập theo tính chẵn lẻ của |index|. // Số chẵn được lưu ở bit cao của (|index| / 2) và số lẻ được // được lưu ở bit thấp của (|index| / 2) ). if (index % 2 != 0) { bộ nhớ->type[index / 2] = (bộ nhớ->type[index / 2] & 0xF0) | loại; 2] = (bộ nhớ->loại [chỉ mục / 2] & 0x0F) | (loại << 4);

AqvmMemory_GetType

Lấy kiểu dữ liệu tại |index| byte trong |memory|. Loại nhỏ hơn 4 bit (0X0F) được trả về thành công. Nếu con trỏ bộ nhớ là NULL thì trả về 0x11. Nếu con trỏ chỉ mục là NULL thì trả về 0x12. Nếu chỉ số vượt quá phạm vi bộ nhớ, 0x13 sẽ được trả về.

uint8_t AqvmMemory_GetType(struct AqvmMemory_Memory* bộ nhớ, size_t chỉ mục) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"" , KHÔNG); trả về 0x11; } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullTypePointer\"", "\"Con trỏ loại là NULL.\"", NULL trả về 0x12); ; } if (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_GetType_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL return 0x13; chỉ mục| byte trong bộ nhớ. // Vì Aqvm lưu trữ loại dữ liệu chiếm 4 bit và uint8_t chiếm 8 bit bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu. Các vị trí lưu trữ // (4 bit cao, 4 bit thấp) được đặt theo tính chẵn lẻ của |index|. |index| / 2) và các số lẻ được // lưu trữ ở các bit thấp của (|index| / 2). if (index % 2 != 0) { return Memory->type[index / 2] & 0x0F; } else { return (memory->type[index / 2] & 0xF0) >> 4;

AqvmMemory_WriteData

Ghi dữ liệu có kích thước |size| được trỏ bởi |data_ptr| vào dữ liệu tại |index|. Trả về 0 khi thành công. Nếu con trỏ bộ nhớ là NULL, -1 được trả về. Nếu con trỏ chỉ mục là NULL, -2 được trả về. Nếu chỉ số vượt quá phạm vi bộ nhớ, -3 sẽ được trả về. Nếu con trỏ dữ liệu là NULL, -4 được trả về.

int AqvmMemory_WriteData(struct AqvmMemory_Memory* bộ nhớ, size_t index, void* data_ptr, size_t size) { if (memory == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_NullMemoryPointer\"", "\"Bộ nhớ con trỏ là NULL.\"", NULL); trả về -1; } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_WriteData_NullTypePointer\"", "\"Con trỏ kiểu là NULL.\"", NULL); trả về -2 } if (chỉ mục> bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL return -3 } if (data_ptr == NULL) { AqvmRuntimewindow_OutputReport ("\"LỖI\"", "\"AqvmMemory_WriteData_NullDataPointer\"", "\"Con trỏ dữ liệu là NULL.\"", NULL); return -4; } // Vì void* không có kích thước cụ thể nên việc di chuyển con trỏ cần phải được // chuyển đổi trước đó di chuyển. memcpy((void*)((uintptr_t)memory->data + index), data_ptr, size return 0;

bộ nhớ.hMã hoàn chỉnh:

// Bản quyền của tác giả AQ 2024, Mọi quyền được bảo lưu. // Chương trình này được cấp phép theo Giấy phép AQ. Bạn có thể tìm thấy giấy phép AQ trong // thư mục gốc.  #include "aqvm/memory/types.h" // Cấu trúc lưu trữ thông tin về bộ nhớ // |type| bộ nhớ //. Vì vậy, một biến uint8_t có thể // lưu trữ 2 loại, 4 bit đầu tiên của biến uint8_t được sử dụng cho byte loại chẵn và 4 bit tiếp theo được sử dụng cho loại danh sách byte // có dạng.h. // |data| là một kiểu con trỏ void* tới bộ nhớ. lưu trữ dữ liệu. struct AqvmMemory_Memory chỉ lưu trữ thông tin của bộ nhớ // Bộ nhớ được bổ sung bởi hàm bytecode khi lưu trữ bytecode // Bộ nhớ của |memory| và |type| là một phần của dữ liệu bytecode bộ nhớ; void* size; system. // Trả về số lượng cảnh báo. , và |size|. // Hàm sẽ phân tích AqvmMemory_Memory Structure và sao chép |data|, // |type|, và |size| architecture. Trả về một con trỏ tới cấu trúc nếu // thành công. AqvmMemory_CreateMemory(void* data, void* type, size_t size); // Lưu Ý: Hàm giải phóng bộ nhớ chỉ của struct. do con trỏ tới dữ liệu và nhập vào struct không được giải phóng. // được quản lý bởi các hàm liên kết. đến byte mã hóa void AqvmMemory_FreeMemory(struct AqvmMemory_Memory* Memory_ptr); // Đặt loại dữ liệu tại |index| phải nhỏ hơn 4 bit. thành công. Trả về -1 nếu bộ nhớ con trỏ là NULL. phạm vi. int AqvmMemory_SetType(const struct AqvmMemory_Memory* bộ nhớ, size_t index, uint8_t type); // Lấy dữ liệu tại byte chỉ mục| // Trả về 0x12 nếu loại con trỏ là NULL. 0x13 if mục nằm ngoài phạm vi bộ nhớ // Ghi dữ liệu |data_ptr| tới kích thước |size| if thành công Trả về -1 nếu bộ nhớ con trỏ là NULL. phạm vi. Trả về // -4 if con trỏ dữ liệu là NULL.int AqvmMemory_WriteData(struct AqvmMemory_Memory* bộ nhớ, size_t chỉ mục, void* data_ptr, size size_t);

bộ nhớ.c

bộ nhớ.cMã hoàn chỉnh:

// Chương trình này được cấp phép theo AQ Giấy phép. Bạn có thể tìm thấy AQ giấy phép trong // thư mục gốc #include "aqvm/memory/memory.h" #include  #bao gồm  #bao gồm  #bao gồm  #include "aqvm/memory/types.h" #include "aqvm/runtime/window/window.h" int AqvmMemory_CheckMemoryConditions() { int Warning_count = 0; if (sizeof(aqint) != 4) { AqvmRuntimewindow_OutputReport( "\" CẢNH BÁO\"", "\"AqvmMemory_CheckMemoryConditions_IntLengthWarning\"", "\"Yêu cầu về độ dài đối với kiểu int không kèm theo định nghĩa " "type ", NULL); (sizeof(aqlong) != 8) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", " \"AqvmMemory_CheckMemoryConditions_LongLengthWarning\"", "\"Yêu cầu về độ dài cho loại dài không thêm vào " "type " " định nghĩa.\", NULL); ++warning_count; } if (sizeof(aqfloat) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_FloatLengthWarning\"", " \"Yêu cầu độ dài cho kiểu float không phù hợp với kiểu " " định nghĩa.\", NULL); } if (sizeof(aqdouble) != 4) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_DoubleLengthWarning\"", "\"Yêu cầu về độ dài cho loại kép không cộng theo định nghĩa loại " ".\"", NULL); (sizeof(aqchar) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_CharLengthWarning\"", "\"Yêu cầu về độ dài cho loại char không có nhiều theo " "gõ " " định nghĩa.\"", NULL); ++warning_count; } if (sizeof(aqbool) != 1) { AqvmRuntimewindow_OutputReport( "\"WARNING\"", "\"AqvmMemory_CheckMemoryConditions_BoolLengthWarning\"", "Yêu cầu về độ dài cho loại bool không đóng theo định nghĩa loại " ".", NULL ); ++warning_count; } if (warning_count == 0) { AqvmRuntimewindow_OutputReport("\"INFO\"", "\"AqvmMemory_CheckMemoryConditions_CheckNormal\"", "\"Không có cảnh báo điều kiện bộ nhớ.\"", NULL); } return Warning_count } struct AqvmMemory_Memory* AqvmMemory_CreateMemory(void* data, void* type; , kích thước size_t) { struct AqvmMemory_Memory* Memory_ptr = (struct AqvmMemory_Memory*)malloc(sizeof(struct AqvmMemory_Memory)); if (memory_ptr == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"","\"AqvmMemory_CreateMemory_MemoryAllocationFailure\"", "\"Không thể cung cấp bộ nhớ phát hiện.\"", NULL); trả về NULL } bộ nhớ_ptr->data = dữ liệu bộ nhớ_ptr->type = bộ nhớ_ptr->size = kích thước; } void AqvmMemory_FreeMemory(struct AqvmMemory_Memory* Memory_ptr) { free(memory_ptr); } int AqvmMemory_SetType(const struct AqvmMemory_Memory* bộ bộ nhớ, size_t chỉ mục,loại uint8_t) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL return - 1; } nếu (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_NullTypePointer\"", "\" Loại bỏ con trỏ là NULL.\"", NULL trả về -2; } nếu như (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_SetType_OutOfMemoryRange\"", "\"Chỉ mục ngoài phạm vi bộ nhớ.\"", NULL); return -3; } if (type > 0x0F) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_SetType_OutOfTypeRange\"", "\" Out of range.\" ", trả về NULL -4 } // index| byte trong bộ nhớ // Vì loại dữ liệu lưu trữ Aqvm sử dụng 4 bit và uint8_t sử dụng 8 bit, // mỗi vị trí loại uint8_t lưu trữ hai loại dữ liệu. Các vị trí lưu trữ // (cao 4 bit, thấp 4 bit) được đặt theo tính chất chẵn của |index|. và các số lẻ được // lưu trữ ở các bit thấp của (|index| / 2). if (index % 2 != 0) { Memory->type[index / 2] = (memory->type[index / 2] & 0xF0) | loại } else { bộ nhớ->type[index / 2] = (bộ nhớ->type[index / 2] & 0x0F) | (loại << 4); } trả về 0; bộ nhớ AqvmMemory_Memory*, size mục_t) { (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_GetType_NullMemoryPointer\"", "\"Con trỏ bộ nhớ là NULL.\"", NULL trả về 0x11 } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport ("\"LỖI\"", "\"AqvmMemory_GetType_NullTypePointer\"", "\"Con trỏ kiểu là NULL.\"", NULL); return 0x12; (chỉ mục > bộ nhớ->kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\ "AqvmMemory_GetType_OutOfMemoryRange\"", "\"Chỉ mục đã hết phạm vi bộ nhớ.\"", NULL); return 0x13; } // Lấy loại dữ liệu tại |index| byte trong bộ nhớ // Vì Aqvm archive loại dữ liệu sử dụng 4 bit và uint8_t sử dụng 8 bit, // mỗi loại uint8_t. vị trí lưu trữ hai loại dữ liệu // (cao 4 bit, thấp 4 bit) được thiết lập theo tính năng lẻ của |index|. // lưu trữ ở bit thấp của (|index| /. 2) và số lẻ được // lưu trữ ở bit thấp của (|index| /. 2). (chỉ mục % 2 != 0) { return bộ nhớ->type[index / 2] & 0x0F; else { return (memory->type[index / 2] & 0xF0) >> 4; } } int AqvmMemory_WriteData(struct AqvmMemory_Memory * bộ nhớ, size_t chỉ mục, void* data_ptr, size_t size) { if (bộ nhớ == NULL) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_NullMemoryPointer\""," \"Ký ức con trỏ là NULL.\"", NULL); trả về -1; } if (bộ nhớ->loại == NULL) { AqvmRuntimewindow_OutputReport("\"ERROR\"", "\"AqvmMemory_WriteData_NullTypePointer\ "", "\"Cuộn con trỏ là NULL.\", NULL); trả về -2 } if (chỉ mục > bộ nhớ-> kích thước) { AqvmRuntimewindow_OutputReport( "\"ERROR\"", "\"AqvmMemory_WriteData_OutOfMemoryRange\"", "\"Chỉ mục nằm ngoài phạm vi bộ nhớ.\"", NULL return -3 } if (data_ptr == NULL) { AqvmRuntimewindow_OutputReport ("\"LỖI\"", "\"AqvmMemory_WriteData_NullDataPointer\"", "\"Con trỏ dữ liệu là NULL.\"", NULL); return -4; } // Vì void* không có công cụ kích thước nên việc chuyển con trỏ memcpy((void*)((uintptr_t)memory->data + index), data_ptr, trả về kích thước 0;memcpy((void*)((uintptr_t)memory->data + index), data_ptr, size return 0 }memcpy((void*)((uintptr_t)memory->data + index), data_ptr, size return 0 }

Thông qua tác phẩm này, một Aqvm kiến ​​trúc đã được hoàn thành, giúp giảm bớt sức mạnh của bộ nhớ Aqvm.

Chúng tôi đang làm việc chăm chỉ hơn trên máy ảo AQ. trang web chính thức của chúng tôi: https://www.axa6.com và Github: https://github.com/aq-org/AQ.

Bài viết này được xuất bản dựa trên Giấy phép AQ: https://github.com/aq-org/AQ/blob/main/LICENSE. lại theo AQ Giấy phép.

Cuối cùng, bài viết về kiến ​​trúc máy xuất sắc máy ảo - AQ end tại đây. trúc bộ nhớ máy ảo xuất sắc - AQ, vui lòng tìm kiếm các bài viết CFSDN hoặc tiếp tục duyệt các bài viết liên quan, tôi hy mong bạn sẽ ủng hộ blog của tôi trong tương lai .

58 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress