2013-11-02 1 views
-1

어셈블러를 배우려고하는데 인수에 함수를 전달할 때 nasm macho32에서 osx가 사용하는 방법으로 다소 혼란 스럽습니다.어셈블러에서 dword와 '스택'의 차이점

저는 Jeff Duntemann의 'Assembly Language Step By Step'책을 읽고 인터넷을 광범위하게 사용하여 osx 32 비트와 64 비트 모두에서 실행되도록 변경했습니다. 그래서

교체, 레지스터 이름을 변경하는 대신 책에서 리눅스 버전과 다른 OSX에 대한

다음
section .data   ; Section containing initialised data 
    EatMsg db "Eat at Joe's!",10 
    EatLen equ $-EatMsg 
section .bss   ; Section containing uninitialised data 
section .text   ; Section containing code 
global start   ; Linker needs this to find the entry point! 

start: 
    nop 
    mov eax, 4   ; Specify sys_write syscall 
    mov ebx, 1   ; Specify File Descriptor 1: Standard Output 
    mov ecx, EatMsg  ; Pass offset of the message 
    mov edx, EatLen  ; Pass the length of the message 
    int 0x80    ; Make syscall to output the text to stdout 

    mov eax, 1   ; Specify Exit syscall 
    mov ebx, 0   ; Return a code of zero 
    int 0x80    ; Make syscall to terminate the program 

    section .data  ; Section containing initialised data 
     EatMsg db "Eat at Joe's!", 0x0a 
     EatLen equ $-EatMsg 
    section .bss  ; Section containing uninitialised data 
    section .text  ; Section containing code 
    global start  ; Linker needs this to find the entry point! 

매우 유사하게 64 비트 버전을 시작합니다 (I 다소 구식 이해) INT의 80H 및 eax로 옮겨진 값에 0x2000000을 더하면 (조금이라도 이것을 이해하지 못한다.) 변경할 것이별로 없다.

반면에 32 비트 Mac 버전은 완전히 다릅니다. 나는 스택 dword에 인수를 푸시하는 것을 볼 수있다. 그래서 나의 질문은 (그리고 긴 프리앰블에 대해 유감스럽게 생각한다) eax가 push되고있는 스택과 dword 사이의 차이점은 무엇이며 왜 우리는 단지 레지스터를 사용하고 왜 사용하지 않는가? 64 비트 버전의 스택 (및 Linux)?

section .data  ; Section containing initialised data 
    EatMsg db "Eat at Joe's!", 0x0a 
    EatLen equ $-EatMsg 
section .bss   ; Section containing uninitialised data 
section .text   ; Section containing code 
global start   ; Linker needs this to find the entry point! 

start: 
    mov eax, 0x4  ; Specify sys_write syscall 
    push dword EatLen ; Pass the length of the message 
    push dword EatMsg ; Pass offset of the message 
    push dword 1  ; Specify File Descriptor 1: Standard Output 
    push eax 
    int 0x80   ; Make syscall to output the text to stdout 
    add esp, 16   ; Move back the stack pointer 

    mov eax, 0x1  ; Specify Exit syscall 
    push dword 0  ; Return a code of zero 
    push eax 
    int 0x80   ; Make syscall to terminate the program 

답변

1

글쎄, 당신은 무엇이 dword인지 잘 모릅니다. HLL을 말하면, 그것은 변수가 아니라 오히려 유형입니다. 따라서 push doword 1은 더블 워드 상수 1을 스택에 푸시한다는 것을 의미합니다. 거기에는 하나의 스택 만 있고, 하나와 레지스터 eax가 모두 거기에 푸시됩니다.

레지스터는 훨씬 빠르기 때문에 특히 오래된 프로세서에서 사용됩니다. Linux ABI (System V ABI의 강하)는 꽤 오래전에 개발되었으며 차이가 매우 클 때 성능이 중요한 시스템에서 자주 사용되었습니다. OSX intel abi는 무시 무시한 속도 저하보다 데스크탑 OSX에서 더 중요한 곳에서 스택 사용의 훨씬 더 젊고, 더 빠르고, 간단합니다. 64 비트 프로세서에서는 더 많은 레지스터가 추가되어 더 효율적으로 사용할 수 있습니다.