所在的位置: swift >> swift介绍 >> Swift汇编一Protocol

Swift汇编一Protocol

由于劳动中来往到Swift汇编与逆向常识,因而整顿了这篇博客。实质与递次无关,第一篇文章并非初学,纯真不过第一篇文章。提倡有必要汇编底子的读者研习。

编译处境:MacOS11.3.1x86_64

Swift:version5.4

汇编格调:intel

甚么是ProtocolWitnessTable

咱们懂得C函数移用是静态派发,浅显来讲也许了解为是用汇编指示call$address来实行。这类方法效率最高,然而精巧性不足。

OC的办法移用完尽是基于动态派发,老是移用objc_msgSend实行。这类方法特别精巧,同意各式Hook黑科技,然而过程最长,效率最低。

在Swift中,协定办法的移用,利用协定办法表的方法实行,也即是ProtocolWitnessTable,下文简称PWT。参考上面这段代码:

protocolDrawable{funcdraw()-Int}structPoint:Drawable{varx,y:Intfuncdraw()-Int{returnx+y}}structLine:Drawable{varlength:Intfuncdraw()-Int{returnlength}}funcfoo()-Int{letp:Drawable=xxxreturnp.draw()}

在foo函数中,变量p并没有明晰的典型,只懂得它遵循Drawable协定,实行了draw办法。然而编译时并不能懂得,移用的是机关体Line依旧Point的draw办法。

是以,PWT的实行方法是:每个类都市有一个办法表(经过数组来实行),内部保管了它用于实行协定的函数的地方。唯有懂得一个类的讯息和函数讯息,就也许实行函数移用。这个办法表,即是PWT。

PWT的汇编实行

除了从理论上领会PWT的观点,咱们还也许从汇编角度来理论感触一下。参考上面这段代码:

protocolDrawable{funcdraw()-Int}structPoint:Drawable{varx,y:Intfuncdraw()-Int{returnx+y}}funcfoo()-Int{letp:Drawable=Point(x:1,y:2)returnp.draw()}

Debug形式下的汇编代码:

swift-ui-test`foo():0xa+0:pushrbp0xa+1:movrbp,rsp0xa+4:pushrxa+6:subrsp,0xxa86a+10:movedi,0x10xa86f+15:movesi,0x20xa+20:call0xae50;swift_ui_test.Point.init(x:Swift.Int,y:Swift.Int)-swift_ui_test.PointatContentView.swift:xa+25:learcx,[rip+0x];typemetadataforswift_ui_test.Point0xa+32:movqwordptr[rbp-0x18],rcx0xa+36:learcx,[rip+0xd];protocolwitnesstableforswift_ui_test.Point:swift_ui_test.Drawableinswift_ui_test0xa88b+43:movqwordptr[rbp-0x10],rcx0xa88f+47:movqwordptr[rbp-0x30],rax0xa+51:movqwordptr[rbp-0x28],rdx0xa+55:movrax,qwordptr[rbp-0x18]0xa89b+59:movrcx,qwordptr[rbp-0x10]0xa89f+63:leardx,[rbp-0x30]0xa8a3+67:movrdi,rdx0xa8a6+70:movrsi,rax0xa8a9+73:movqwordptr[rbp-0x38],rax0xa8ad+77:movqwordptr[rbp-0x40],rcx0xa8b1+81:movqwordptr[rbp-0x48],rdx0xa8b5+85:call0xae60;__swift_project_boxed_opaque_existential_1at


转载请注明:http://www.aierlanlan.com/rzfs/1007.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了