最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

arm64 實現(xiàn)閉包轉C函數

2023-03-08 11:26 作者:你敢敢我就我敢  | 我要投稿

調用約定

arm64的C調用約定如下:

首八個不超過8bytes的非浮點數使用r0-r7寄存器

首八個浮點數使用d0-d7寄存器

大于八個參數則使用棧傳遞

結構體分為三種情況

  1. 不超過8bytes,那么此結構體直接使用上述規(guī)則傳遞

  2. 超過8bytes但不超過16bytes,那么此結構體使用兩個64bits寄存器傳輸

  3. 超過16bytes,傳遞結構體指針


返回值若不超過8bytes,則使用r0或d0傳遞,否則調用者使用x8傳遞接受對象的指針,被調用者將值寫入指針

實現(xiàn)

下面將使用Rust語言實現(xiàn)少于七個參數無浮點的閉包轉換

閉包是一個含有狀態(tài)的“函數”,使用起來十分方便,但是要使用一些C函數回調的時候就很不友好了

下面我們來“改造”閉包

一個閉包可以當作一個結構體,他當然也是有地址的

于是對于一個閉包

Fn(T) -> R

我們可以改造為

extern "C" fn(*const?(), T) -> R

要實現(xiàn)這點也不難,只需要將寄存器一一往后排,再將x0寄存器賦值對應指針

難點是如何生成這樣的機器碼

生成機器碼

通過上面的分析和查閱資料,找到我們需要使用的指令

BR

我們先來反匯編分析C函數的跳轉

C
ASM

可見其跳轉使用了BLR指令,那么為什么我們使用BR指令進行跳轉呢?

因為我們不需要“返回”

BLR指令的含義為:存儲返回地址到LR(x30)寄存器

RET指令的含義為:使用LR寄存器進行返回 (return)

那么使用BR指令直接跳轉即可,不需要動LR寄存器

MOVK

MOVK指令可以將一個16位立即數偏移存入指定寄存器,并且保留寄存器其他位的數值(即MOV'Keep')

那么我們可以硬編碼一個指針進入寄存器,以實現(xiàn)尋址,即:

MOVK x0, part0, LSL 0

MOVK x0, part1, LSL 16

MOVK x0, part2, LSL 32

MOVK x0, part3, LSL 48

使用四條指令即可存儲一個指針進入寄存器

MOV (register)

我們需要移動寄存器,那么是肯定需要使用MOV指令的了

機器碼生成

接下來就是生成機器碼,機器碼的詳細定義請參閱Arm手冊(見文末)

通過閱讀arm手冊我們得到這幾個指令的機器碼生成函數

然后就是期待已久的機器碼生成環(huán)節(jié)~

首先我們定義參數

根據參數列表生成對應的機器碼

規(guī)則如下:

如果小于32bits,則使用Wn傳遞

否則使用Xn傳遞

第一個參數為x0, 將其轉移至x1

第二個參數為x1, 將其轉移至x2

...?以此類推

然后將參數指針傳入x0, 函數指針傳入Xn (注意不可占用x8)

那么對于參數列表,我們可以做如下工作

遍歷參數列表,對寄存器數字遞增

然后將生成的機器碼反轉

第二個參數為x1, 將其轉移至x2

第一個參數為x0, 將其轉移至x1

(防止破壞參數)

最后存入參數指針和函數指針

小端序

那么到這里,機器碼的生成就完畢了,接下來就是將其寫入可執(zhí)行內存并嘗試執(zhí)行,此內容詳見文末(VirtualAlloc / mmap)

接下來就是執(zhí)行測試!

完美通過!

本文源碼:https://github.com/LaoLittle/binary-learn

Armv8 手冊:https://developer.arm.com/documentation/ddi0487/fc/

VirtualAlloc / VirtualProtect?/?VirtualFree?:??https://learn.microsoft.com/en-us/windows/win32/api/memoryapi

mmap / munmap / mprotect :?https://linux.die.net/man/2

arm64 實現(xiàn)閉包轉C函數的評論 (共 條)

分享到微博請遵守國家法律
武义县| 金溪县| 华池县| 陇川县| 民乐县| 民丰县| 武山县| 禄丰县| 聂荣县| 瓮安县| 冷水江市| 电白县| 井冈山市| 大悟县| 云和县| 平凉市| 东源县| 苏州市| 东安县| 大庆市| 南丰县| 东方市| 塔河县| 葫芦岛市| 忻州市| 小金县| 抚州市| 万宁市| 波密县| 休宁县| 双鸭山市| 壶关县| 宣恩县| 平山县| 原阳县| 高台县| 商洛市| 汉中市| 彝良县| 耿马| 台北市|