【HSP3】HSP3x64サポートの為の関数呼び出しアセンブリv2(これはひどい)

前のが正常動作してなかったので修正。ひどすぎて読みずらいぞ!

前のが正常動作してなかったので修正。ひどすぎて読みずらいぞ!

  • hk1v
  • 2014/3/6 0:53
  • タグ:
  • タグはありません
; masm64 (x64)
;.686
;.mmx
;.xmm
;.model flat
;_TEXT64 segment page public use64 'CODE'
;		align 16

; fastcall!!
;PUBLIC C call_extfunc64
.code
align 16
PUBLIC call_extfunc64
call_extfunc64 PROC	

	; rcx = 第1引数(関数のポインタ)
	; rdx = 第2引数(引数が入ったINT64の配列)
	; r8 =  第3引数(引数情報(int=0,double(float)=1)が入ったINT64の配列)
	; r9 =  第4引数(引数の数)
	; rax = 戻り値

; レジスタの退避
	push r12
	push r13
	push r14
	push r15

; 引数が0~4の時はサイズ40
; 5以降は 16ずつ増える
; 5-6  56
; 7-8  72
; 9-10 88

; r10~r11はテンポラリ用
; r12 は関数のアドレス保持に使用中の為
; r13 をサイズ保持用レジスタ
; r14 をrdx退避使用
	mov r14, rdx
; r15 は引数の数で、使用中
	mov r13, 40
; if r13 <= 4
	cmp r13, 4
	jbe JMP1
; 5以上の処理
;(d+=8*(num-4))
	mov r10, r9
	sub r10, 4
; 掛け算*8なので算術シフトする
	shl r10, 3
	add r13, r10
;if d\16 == 0 : d+=8
	mov rax, r13
	cdq
	and	rdx, 15
	add	rax, rdx
	and	rax, 15
	sub	rax, rdx
	cmp rax, 0
	jne JMP1
	add r13, 8
JMP1:
; 復元(r14->rdx)
	mov rdx, r14
	mov r11, r13

	sub rsp, r11

; コピー
	mov r12, rcx
	mov r13, rdx
	mov r14, r8
	mov r15, r9

; r10-r11 レジスタ (テンポラリ用レジスタ)
; 0クリア
;	xor r10, r10
;	xor r11, r11

; 引数1~4の時はレジスタに格納、5以降はスタック

; 第1引数
; if num > 0
	cmp r15, 0
	jg FLAG1
	jmp FLAG1END
FLAG1:
; r14のポインタからr10 レジスタに中身コピー
	mov r10, qword ptr [r14+0]
; int or double?
	cmp r10, 0
	je FLAG1INT
	; doubleなのでxmm?へ
	movq xmm0, qword ptr [r13+0]
	jmp FLAG1END
FLAG1INT:
	mov rcx, qword ptr [r13+0]
FLAG1END:

; 第2引数
; if num > 1
	cmp r15, 1
	jg FLAG2
	jmp FLAG2END
FLAG2:
; r14のポインタからr10 レジスタに中身コピー
	mov r10, qword ptr [r14+8]
; int or double?
	cmp r10, 0
	je FLAG2INT
	; doubleなのでxmm?へ
	movq xmm1, qword ptr [r13+8]
	jmp FLAG2END
FLAG2INT:
	mov rdx, qword ptr [r13+8]
FLAG2END:

; 第3引数
; if num > 2
	cmp r15, 2
	jg FLAG3
	jmp FLAG3END
FLAG3:
; r14のポインタからr10 レジスタに中身コピー
	mov r10, qword ptr [r14+16]
; int or double?
	cmp r10, 0
	je FLAG3INT
	; doubleなのでxmm?へ
	movq xmm2, qword ptr [r13+16]
	jmp FLAG3END
FLAG3INT:
	mov r8, qword ptr [r13+16]
FLAG3END:

; 第4引数
; if num > 3
	cmp r15, 3
	jg FLAG4
	jmp FLAG4END
FLAG4:
; r14のポインタからr10 レジスタに中身コピー
	mov r10, qword ptr [r14+24]
; int or double?
	cmp r10, 0
	je FLAG4INT
	; doubleなのでxmm?へ
	movq xmm3, qword ptr [r13+24]
	jmp FLAG4END
FLAG4INT:
	mov r9, qword ptr [r13+24]
FLAG4END:

; 第5引数以降
; if num < 5 : CALLFUNCに飛ぶ
	cmp r15, 5
	jl CALLFUNC
; ↓5以降はRSPスタックに積む(後ろから積む)
	mov r10, r15
	jmp PUSHCHECK
	PUSHSTACK:
		;push qword ptr [r13+r10*8]
		mov	rax, qword ptr [r13+r10*8]
		mov	qword ptr [rsp+r10*8], rax
	PUSHCHECK:
		dec	r10
		; ~0~3の時は抜ける
		cmp r10, 3
		jg PUSHSTACK
; ↑

CALLFUNC:
; 呼出
	mov r13, r11
	call r12
	mov r11, r13

; 終了
	add	rsp, r11

; レジスタ後始末
	pop r15
	pop r14
	pop r13
	pop r12

	ret

call_extfunc64 ENDP
;
End