Tôi đã viết một máy ảo trong C có hiệu suất khá cho một máy ảo không phải JIT, nhưng tôi muốn tìm hiểu một cái gì đó mới và cải thiện hiệu suất. Việc triển khai hiện tại của tôi chỉ đơn giản là sử dụng một công tắc để dịch từ bytecode VM sang các chỉ lệnh, được biên dịch thành một bảng nhảy. Như tôi đã nói, hiệu suất tốt cho nó là gì, nhưng tôi đã đánh một rào cản chỉ có thể được khắc phục bằng trình biên dịch JIT.Viết một trình biên dịch JIT trong assembly
Tôi đã hỏi một câu hỏi tương tự cách đây không lâu về mã tự sửa đổi, nhưng tôi đã nhận ra rằng tôi đã không hỏi đúng câu hỏi.
Vì vậy, mục tiêu của tôi là viết trình biên dịch JIT cho máy ảo C này và tôi muốn thực hiện nó trong lắp ráp x86. (Tôi đang sử dụng NASM như assembler của tôi) Tôi không hoàn toàn chắc chắn làm thế nào để đi về việc này. Tôi cảm thấy thoải mái với việc lắp ráp, và tôi đã xem xét một số ví dụ mã tự sửa đổi, nhưng tôi đã không tìm ra cách để tạo ra mã nguồn.
Khối chính của tôi cho đến nay là sao chép hướng dẫn đến một phần bộ nhớ thực thi, với đối số của tôi. Tôi biết rằng tôi có thể gắn nhãn một dòng nhất định trong NASM và sao chép toàn bộ dòng từ địa chỉ đó bằng các đối số tĩnh, nhưng điều đó không phải là rất động và không hoạt động đối với trình biên dịch JIT. Tôi cần để có thể giải thích các lệnh từ bytecode, sao chép nó vào bộ nhớ thực thi, giải thích đối số đầu tiên, sao chép nó vào bộ nhớ, sau đó giải thích đối số thứ hai, và sao chép nó vào bộ nhớ.
Tôi đã được thông báo về một số thư viện có thể làm nhiệm vụ này dễ dàng hơn, chẳng hạn như GNU sét và thậm chí là LLVM. Tuy nhiên, tôi muốn viết điều này bằng tay trước, để hiểu cách nó hoạt động, trước khi sử dụng các tài nguyên bên ngoài.
Có bất kỳ tài nguyên hoặc ví dụ nào mà cộng đồng này có thể cung cấp để giúp tôi bắt đầu nhiệm vụ này không? Một ví dụ đơn giản cho thấy hai hoặc ba hướng dẫn như "thêm" và "mov" được sử dụng để tạo mã thực thi, với các đối số, động, trong bộ nhớ, sẽ làm điều kỳ diệu.
Chỉ vì một jitter tạo ra mã máy không * không * có nghĩa là bản thân nó cần phải được viết trong hội đồng. Nó không có ý nghĩa để làm như vậy. –
Một bước trung gian để thử là gửi luồng bằng cách sử dụng phần mở rộng goto được tính toán của GCC (sử dụng 'void * optable [] = {&& op_add, && op_subtract, ...}' và mỗi toán hạng là 'op_add: ... goto * optable [* ip ++] ; '). Tôi đã thấy những lợi ích to lớn trong các phiên dịch viên chuyển đổi như bạn mô tả. –