在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
Plan 9汇编寄存器:数据寄存器:R0-R7,地址寄存器:A0-A7,浮点寄存器:F0-F7。 伪栈寄存器:FP, SP, TOS。 FP是frame pointer,0(FP)是第一个参数,4(FP)是第二个。 SP是local stack pointer,保存自动变量。0(SP)是第一个。 TOS是top of stack寄存器,用来保存过程的参数,保存局部变量。 汇编器可以有一个变量名,比如p+0(FP),表示p是第一个参数,这个变量保存在符号表内,但是对程序运行没有影响。 数据:所有的外部引用都需通过伪寄存器: PC(virtual Program Counter)/SB(Static Base register)。 PC用来控制程序执行,SB用来引用全局变量。比如: 把全局数组的地址压栈:MOVL $array(SB), TOS。 把全局数组的第二个元素压栈:MOVL array+4(SB), TOS local<>+4(SB)是本地变量,只在本文件可见。 定义流程:TEXT sum(SB), $0 TEXT是一个伪指令,用来定义入口点。后面的参数是函数名,然后是栈大小,通常为0。 中间可以有一个指定loader的选项,设置为1暂停函数的profiling。 设置为2允许一个程序中有多个TEXT符号。 子流程把运算结果放到R0中。浮点的结果放在F0中。 子流程负责保存自己的寄存器,为caller saves模式。 Go语言汇编Go语言的汇编基于Plan 9的汇编,但是有一些不同。最主要的一个区别是,Go语言的汇编指令不一定直接对应机器表示。有一些直接对应,有一些则不是。 编译器产生的是一些中间码,具体的机器指令是在汇编生成之后才定下来的(Linker的工作)。 FUNCDATA和PCDATA是编译器产生的,用于保存一些给垃圾收集的信息。 Go语言的汇编和Plan 9的另一个不同是操作符的优先级。比如3&1<<2被解释成(3&1)<<2。 符号:Go语言有4个伪寄存器,实际是对内存位置的一个引用。 FP: 帧指针,保存参数和本地变量 PC:程序指针,负责跳转和流程控制 SB: 静态基指针,全局变量 SP:栈指针,栈顶 所有的符号全部携程FP和SB的偏移的形式: SB伪寄存器用来表示全局的变量或者函数,不如foo(SB)用来表示foo的地址。加<>表示符号本文件内可见。 FP是用来保存参数的。(0)FP是第一个参数(8)FP是第二个(如果是64位机器)。 SP指向本地栈顶,分别用x-8(SP), y-4(SP)表示变量。 直接的jmp或者call指令,只能指向text符号,不能是符号的偏移。 指令:TEXT指令定义一个符号,后面紧跟函数体。 DATA指令定义一个section的内存,这段内存并不会被初始化。 DATA symbol+offset(SB)/width, value GLOBAL指令定义一个符号是全局的 GLOBL divtab<>(SB), RODATA, $64 GLOBL runtime·tlsoffset(SB), NOPTR, $4 divtab是制度的64byte的表格,保存4个byte的整形。tlsoffset是,4byte的no pointers 指令修饰符:DUPOK:允许一个二进制文件里有多个实例 NOSPLIT: FOR TEXT,routine或者routine的子函数,必须把栈的空间的头填满,用来保护栈分隔 RODATA:FOR DATA/GLOBL,把数据放在只读段 NOPTR: FOR DATA/GLOBL,数据没有指针,不需要被垃圾收集扫描 WRAPPER: FOR TEXT,wrapper function,不需要被以禁用recover计数 NEEDCTXT:FOR TEXT,闭包 Runtime协作:NOPTR和RODATA的数据不需要被垃圾收集。比指针还要小的数据也被当做NOPTR。不要在go汇编里写非只读数据。 语法:plan9函数调用协议中采用的是caller-save的模式,也就是由调用者负责保存寄存器。 TEXT !$Add(SB),$0 MOVQ x+0(FP), BX MOVQ y+8(FP), BP ADDQ BP, BX MOVQ BX, ret+16(FP) RET a+8(FP) 变量名+偏移(寄存器)。FP其实就是BP(栈基址寄存器上移一个机器字长位置的内存地址)。 TEXT ·add(SB),NOSPLIT,$0 00B7分隔了包名和变量名。NOSPLIT表示不用写入参数的大小,$0表示参数的大小,因为制定了NOSPLIT所以写0 汇编文件的名字甚至变量名称并不重要。 MOVQ $0, DX //put 0 into DX register. Q means quadword which is 8 bytes. L for 4 bytes. (src, destination) order ¥24-8表示24字节的帧,和8个字节的参数 Go Array有不是指向第一个元素的指针,而是代表整个数组。赋值或者传递的时候是有一个copy的。 Go slice有三个部分, 一个指针,一个长度,一个容量,指针8个字节,长度和容量4个字节 一个slice没有固定的长度。slice不能指定长度。一个slice如果要增加capacity必须创建一个新的容量更大的slice,并copy内容过去。
Examples:
|
请发表评论