Tôi đang làm việc với một số chức năng trampoline để sử dụng với mức gọi cao hơn trong C/Objective-C, một chút xoắn trên đường Apple does it.Xóa đối số khỏi ngăn xếp trong i386, lắp ráp ARM
Nếu bạn quen thuộc với cách Objective-C IMP
hoạt động, về cơ bản nó là một con trỏ hàm trong đó hai đối số đầu tiên là người nhận thư và tên của bộ chọn thư, chẳng hạn như void(*)(id obj, SEL sel, ...)
. Các phiên bản gần đây của thời gian chạy cho phép triển khai phương pháp được tổng hợp tại thời gian chạy bằng cách sử dụng các khối C, như void(^)(id obj, ...)
. Những khối này không có bộ chọn; thời gian chạy tạo ra một tấm bạt lò xo ghi đè lên bộ chọn với người nhận, người nhận với con trỏ khối, và sau đó di chuyển trên thực hiện nó.
Tôi muốn làm điều gì đó mơ hồ tương tự như không có hoặc là trong hai đối số đầu tiên, để đối số cho khối này giống hệt như đối số của phương thức truyền thống gửi. mục đích, ví dụ: void(*)(Block *, ...)
. Điều này đòi hỏi chỉ sao chép trong con trỏ khối, và tôi cho rằng loại bỏ một đối số.
__a1a2_tramphead_argonly:
popl %eax
andl $0xFFFFFFF8, %eax
subl $0x1000, %eax
movl 4(%esp), %ecx // self -> ecx
movl %ecx, 8(%esp) // ecx -> _cmd
movl (%eax), %ecx // blockPtr -> ecx
movl %ecx, 4(%esp) // ecx -> self
jmp *12(%ecx) // tail to block->invoke
Đây là lắp ráp Tôi có trên ARM:
__a1a2_tramphead_argonly:
// calculate the trampoline's index (512 entries, 8 bytes each)
#ifdef _ARM_ARCH_7
// PC bias is only 4, no need to correct with 8-byte trampolines
ubfx r1, r1, #3, #9
#else
sub r1, r1, #8 // correct PC bias
lsl r1, r1, #20
lsr r1, r1, #23
#endif
// load block pointer from trampoline's data
adr r12, __a1a2_tramphead_argonly // text page
sub r12, r12, #4096 // data page precedes text page
ldr r12, [r12, r1, LSL #3] // load block pointer from data + index*8
// shuffle parameters
mov r1, r0 // _cmd = self
mov r0, r12 // self = block pointer
// tail call block->invoke
ldr pc, [r12, #12]
đang tương tự tồn tại cho x86_64; mã ở trên là như vậy đến nay trực tiếp từ Apple. Đối với kiến thức cá nhân, tôi tự hỏi bắt đầu từ đâu với một cuộc tranh luận, để đối số đầu tiên (cái được sử dụng để là người nhận) là khối chữ, thứ hai là đối số thực đầu tiên, v.v.
Tôi cực kỳ ngớ ngẩn với ASM, vì vậy mọi trợ giúp đều được đánh giá cao. Tất cả mọi thứ tôi đã cố gắng đã thổi lên theo những cách ngày càng thú vị. Cảm ơn trước.
Hãy cẩn thận, nhiều bản phân phối Linux hiện đang trong quá trình di chuyển đến ABI nổi cứng của ARM. Điều đó sẽ hoàn toàn phá vỡ mọi thứ cho bạn, một lần nữa. – ams
Thật thú vị, tôi sẽ ghi nhớ điều đó trong tương lai. Điều này chủ yếu nhắm vào Darwin, tuy nhiên. Cảm ơn bạn! Chỉnh sửa: Điều đó có nghĩa là ARMV6 và ARMV7, ít nhất là trong thời gian này. – zwaldowski