어셈블리 언어를 다시 배우는 중입니다. 지금까지 가지고있는 유일한 문제는 C에 대한 호출이었습니다. 제가 가지고있는 책은 32 비트에 맞추어졌고 64 비트로 작업하고 있습니다. 명백하게 호출 규칙에 큰 차이가 있으며 http://www.x86-64.org/documentation 사이트가 다운되었습니다. 그래서 일부 파기/테스트 후, C로 더미 프로그램을 컴파일하고 3 일을 보냈다. 다른 사람들에게 도움이된다면 내 결과를 게시 할 것이라고 생각했다.64 비트 ASM에서 Printf를 호출 할 때 params는 어떻게 전달됩니까?
RAX에 부동 소수점 수를 입력해야합니까? 스택 패딩 "섀도우 스페이스"가 16 비트 또는 32 비트입니까? 작은 프로그램에서 스택을 정렬 할 수있는 매크로입니까? 정렬을 사용하여 코드를 NOP로 채울 수 있다는 것을 알고 스택 프레임에 대해 확신하지 못했습니다.
; pf.asm compiled with 'nasm -o pf.o -f elf64 -g -F stabs'
; linked with 'gcc -o pf pf.o'
; 64-bit Bodhi (ubuntu) linux
%include "amd64_abi.mac"
[SECTION .data]
First_string: db "First string.",10,"%s", "%d is an integer. So is %d",10
db "Floats XMM0:%5.7f XMM1:%.6le XMM2:%lg",10,0
Second_String: db "This is the second string... %s's are not interpreted here.",10
db " Neither are %d's nor %f's. 'Cause it is a passed value.", 10, 0
; Just a regular string for insert.
[SECTION .bss]
[SECTION .text]
EXTERN printf
GLOBAL main
main:
_preserve_64AMD_ABI_regs ; Saves RBP, RBX, R12-R15
mov rdi, First_string ; Start of string to be formatted. Null terminated
mov rsi, Second_String ; String addy of first %s in main string. Not interpretted
mov rcx, 0456 ; Second Integer (Register is specific for ordered arguments.)
mov rdx,; First integer (Order of assignment does not matter.)
; Order of Integer/Pointer Registers:
; $1:RDI $2:RSI $3:RDX $4:RCX $5:R8 $6:R9
mov rax,0AABBCCh ; Test value to be stored in xmm0
cvtsi2sd xmm0, rax ; Convert quad to scalar double
mov rax,003333h ; Test value to be stored in xmm1
cvtsi2sd xmm1, rax ; Convert quad to scalar double
cvtsi2sd xmm2, rax ; Convert quad to scalar double
divsd xmm2, xmm0 ; Divide scalar double
sub rsp, 16 ; Allocates 16 byte shadow memory
_prealign_stack_to16 ; Move to the lower end 16byte boundry (Seg-Fault otherwise)
; mov rax, 3 ; Count of xmm registers used for floats. ?!needed?!
Before_Call:
call printf ; Send the formatted string to C-printf
_return_aligned_stack ; Returns RSP to the previous alignment
add rsp, 16 ; reallocate shadow memory
_restore_64AMD_ABI_regs_RET
; Ends pf.asm
; amd64_abi.mac
; Aligns stack (RSP) to 16 byte boundry, padding needed amount in rbx
%macro _preserve_64AMD_ABI_regs 0
push rbp
mov rbp, rsp
push rbx
push r12
push r13
push r14
push r15
%endmacro
%macro _restore_64AMD_ABI_regs_RET 0
pop r15
pop r14
pop r13
pop r12
pop rbx
mov rsp, rbp
pop rbp
ret
%endmacro
%macro _prealign_stack_to16 0
mov rbx, 0Fh ; Bit mask for low 4-bits 10000b = 16 :: 01111b = 15b
and rbx, rsp ; get bits 0-3 into rbx
sub rsp, rbx ; remove them from rsp, rounding down to multiple of 16 (10h)
%endmacro
; De-aligns stack (RSP)from 16 byte boundry using saved rbx offset
%macro _return_aligned_stack 0
add rsp, rbx
%endmacro
OUTPUT : 첫 번째 문자열. 이것은 두 번째 문자열입니다 ... % s은 (는) 여기에서 해석되지 않습니다. % d 또는 % f도 아닙니다. 왜냐하면 그것은 가치가 있기 때문입니다. 123은 정수입니다. 11189196.0000000 XMM1 : 1.310700e + 04 XMM2 : 0.0011714
자료 : 시스템 V ABI의 v0.96 : http://www.uclibc.org/docs/psABI-x86_64.pdf은 (그것은 사이트가 다운 x86-64.org에서 사용할 수 없습니다) 어셈블리 언어 그래서 456 수레 XMM0입니다 단계별. 제프 Duntemann 12 장 인텔 64 비트 명령어 세트. http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
명백한 접근 방식을 : 당신이 모든
RSP
을 조정하지 않아도을 의미 명시 적으로 할당하지 않고 스택 포인터 아래에 128 바이트를 사용할 수 있기 때문에 또한, 앞서 언급 빨간색 영역, 잎 기능에 유용하다 먼저 C로 코드를 작성하고 C 컴파일러에서 어셈블리를 생성하도록하십시오. 결코 틀린 일은 아닙니다. –