분할 오류는 나쁜 스택 정렬 (misaligned_stack_error
)에서 비롯됩니다.
그런 문제가 발생하면 항상 GDB으로 프로그램을 실행 해보십시오. 일반적으로 더 많은 정보를 제공합니다.
그러나 C 라이브러리에서 함수를 호출 할 때 스택을 16 바이트 경계에 정렬해야합니다.
Mac OS X 32 비트 ABI에 대한 요구 사항입니다 (64 비트 ABI의 경우 SYS V 호출 규칙을 사용함).
는
[bits 32]
section .data
hello db "Program name: %s (%i CLI args)", 10, 0
section .text
global start
extern _exit
extern _printf
start:
; Store 'argc' into EAX
pop eax
; Store 'argv' into EBX
pop ebx
; Align stack on a 16 bytes boundary,
; as we'll use C library functions
mov ebp, esp
and esp, 0xFFFFFFF0
; Stack space for local variables
; A little more space than needed, but that will
; ensure the stack is still aligned
sub esp, 16
; Call 'printf': printf(hello, ebx, eax);
mov dword[ esp ], hello
mov dword[ esp + 4 ], ebx
mov dword[ esp + 8 ], eax
call _printf
; Call 'exit': exit(0);
mov dword[ esp ], 0
call _exit
는 사용하여 컴파일 :
을 그래서 여기
(설명을 그냥 이후) 실행 파일 이름을 인쇄 할 프로그램의 작업 버전뿐만 아니라 CLI 인수의 수입니다
nasm -f macho -o test.o test.asm
ld -o test test.o -arch i386 -lc -macosx_version_min 10.6
설명 :
우리는 어떤 REGIST에서 첫 번째 저장소 argc
및 argv
ERS : 당신은 당신이 정렬 스택을 유지 가정 start
의 시작 부분에 한 번만이 작업을 수행 할 수 있습니다
mov ebp, esp
and esp, 0xFFFFFFF0
:
pop eax
pop ebx
을 그리고 그 다음 우리는 16 바이트 경계에 스택을 정렬 지역 변수를위한 공간을 만들 때.
그런 다음 로컬 변수에 필요한 공간 인 을 만들어 스택의 정렬 상태를 유지합니다.
여기서 스택 인수를 3 개만 확보 할 필요가 있지만 스택을 정렬 상태로 유지하기 위해 4를위한 공간을 만듭니다.
mov dword[ esp ], hello
mov dword[ esp + 4 ], ebx
mov dword[ esp + 8 ], eax
그런 다음 단순히 C 라이브러리 함수를 호출, 당신은 OK 수 있습니다 : sub esp, 16
그런 다음 호출에 대해 인수를 준비하기 위해, 그 공간에 값을 이동할 수 있습니다.
참고 유용한 정보는 this answer (x86 Assembly on a Mac)에 있습니다.
생성 된 바이너리가 32 비트인지 확인 하시겠습니까? – Macmade
64 비트에서 실행되는 경우 호출 규칙은 cdecl이 아니지만 sys V. – Macmade
@Macmade, 정보를 제공해 주셔서 감사합니다! 64 비트 프로그램을 만들고 싶다면이 점을 명심하십시오. 프로그램은 * ld'에'-arch i386'을 지정했기 때문에 x86 만 있어야합니다. 컴퓨터에서 동일한 코드를 빌드하고 실행하려고하면 어떻게됩니까? – mcandre