2014-03-24 2 views
1

내가 ASM에 새로운 오전, 나는이 기능을 사용하여 기본 안녕하세요 세계 프로그램을 만들려고 해요 :하지만,ASM의 x86_64에 안녕하세요 세계 프로그램

section .text 
    global main 

print_msg: 

    push rbp 
    mov rbp, rsp 

    mov rax, 1 
    mov rdi, 1 
    mov rsi, Buffer  ;to change 
    mov rdx, BufferSize ;to change 
    syscall 

    mov rsp, rbp 
    pop rbp 

    ret 

main: 

    mov rdi, Buffer 
    mov rsi, BufferSize 
    call print_msg 

    mov rax, 60 
    mov rdi, 0 
    syscall 

section .rodata 

Buffer:  db 'Hello, world !', 0x0A 
BufferSize: equ $-Buffer 

이 코드는 실제로 작동 만 내가 직접 버퍼 복사로 인해 RDX의 RSI와 버퍼 크기에, 내 "print_msg"기능에,하지만이 두 레지스터에 수신 가지 인자를 복사 할, 내가 좋아하는 것을 보았다

mov rsi, [rsp + 8] 
mov rdx, [rsp + 12] 

을하지만 그것은 여기에 작동하지 않습니다.

mov rdi, Buffer 
mov rsi, BufferSize 
call print_msg 

당신이 인수 rdirsi로드, 왜 당신이 그들을 호출 된 함수의 스택에있을 것으로 예상합니까 : 코드도 보여으로

답변

2

- 64는, 인수를 전달하는 레지스터를 사용 ? CALL은 레지스터에 아무 것도 수행하지 않고 반환 주소 만 스택에 저장합니다. 따라서 두 가지 주장은 여전히 ​​rdirsi에 행복합니다. 올바른 위치에 그냥 mov을 : 당신이 할 수있는

mov rdx, rsi 
mov rsi, rdi 
mov rax, 1 
mov rdi, 1 
syscall 
1

; 호출하기 전에 인수를 푸시해야합니다. 이처럼 :

push Buffer 
push BufferSize 
call print_msg 
add rsp, 16 

그런 다음 그들은 같은 접근 가능 [RBP + 16], [RBP가 + 24]. 그러나 그것은 나쁜 생각입니다. 일반적으로 인정되는 x86_64 호출 규칙에서는 처음 몇 개의 인수를 레지스터에 전달해야합니다. Linux에서는 RDI, RSI, RDX, RCX, R8 및 R9입니다. 따라서 RSI와 RDI를 함수 내부에서 재설정하지 않는 한 (현재와 마찬가지로) 훌륭합니다.

관련 문제