2012-09-22 3 views
3

흥미로운 문제가있는 것 같지만, 나는 뻔뻔스럽게 뭔가 잘못하고 있습니다.nasm 64 비트 푸시 qword?

제 문제는 스택에 AAAABBBBCCCC를 푸시하고 stdout을 통해 인쇄하려고한다는 것입니다. 그러나 그것은 내 x86_64 환경에서 push 0x41414141 푸시 4141414100000000 것 같습니다.

그래서 다음과 같은 코드 블록 :

global _start 
    section .text 
    _start: 
    push 0x43434343 ; CCCC 
    push 0x42424242 ; BBBB 
    push 0x41414141 ; AAAA 
    xor rax,rax  ; Zero RAX 
    mov byte al,0x1 ; 1 for sys_write 
    mov rdi,rax  ; 1 for stdout 
    mov rsi,rsp  ; RSP for source 
    mov byte dl,0xC ; 12 
    syscall   

    xor rax,rax  ; Zero RAX 
    mov al, 0x3C  ; 60 for sys_edxit 
    cdq    ; 0 for clean exit. 
    syscall 

출력 AAAABBBB, 난 단지 8 바이트 무슨 생각으로는, 실제로 내가 요청한 (12)이었다. 출력 파일에 파이프되어 hexedit에서 보았을 때, 나는 그것이 414141410000000042424242을 표시하고있는 것으로 나타났습니다.

push 명령어는 dword 값을 푸시합니다. 크기가 스택 qword? 나는 이것을 생각하는 것이 맞습니까?

추가 바이트를 고려하고 내 길이를 20으로 변경하면 적절하게 피할 수 있습니다. 그러나 이는 sys_open과 같은 문제를 일으킬 수 있습니다.

제 질문은 무엇이 잘못 되었습니까?

+0

@DCoder : 'push' 명령어의 연산 의사 코드에 따르면, 피연산자가 부호 확장된다는 점에서 맞습니다. --- 음 ... 그는 단지 그의 코멘트를 삭제 했습니까? – IdiotFromOutOfNowhere

답변

7

64 비트 코드의 경우 스택 (RSP)은 항상 8 바이트 경계에 정렬됩니다. "push qword imm64"명령도 없습니다 (참고 참조).

내 충고는 "AAAABBBBCCCC"문자열을 데이터 섹션 (또는 ".rodata")에 저장하는 것입니다. 당신의 왜곡이있을 수 있습니다 보존

대안 :

sub rsp,16 
mov [rsp],'AAAA' 
mov [rsp+4],'BBBB' 
mov [rsp+8],'CCCC' 
.... 
add rsp,16 

참고 : AMD 설명서는 "밀어 imm64"명령이 말했다. AMD의 매뉴얼은 잘못되었습니다.이 명령어는 32 비트 즉치 (부호 확장을 사용하여 64 비트)를 실제로 푸시합니다.

+0

스택은 __not__ 항상 q 워드 정렬되었습니다! 나는 그 밖의 모든 것에 동의한다 ... – IdiotFromOutOfNowhere

관련 문제