2017-12-24 45 views
1

간단한 예제와 gdb를 사용하여 어셈블리 프로그래밍과 익스 프레싱에 익숙하지 않습니다.세그먼트 화 오류가 발생하지 않은 이유는 무엇입니까?

1.asm

section .text 
    global _start 
    extern _print_func 

_start: 
    push str 
    movzx rdx, byte [str_len] 
    push dx ; <--- typo here, should be rdx 
    call _print_func 

    mov rax, 60 
    syscall 

section .data 
    str: db 'Some data',0x0A,0x0D 
    str_len: db $ - str 

2.asm

section .text 
    global _print_func 

_print_func: 
    pop rbx 
    pop rdx 
    pop rsi 
    mov rax, 0x01 
    mov rdi, 0x01 
    syscall 
    push rbx 
    ret 

section .data 
    str: db 'Some string',0x0A,0x0D 
    str_len: db $ - str 

(ld로) 연결, 컴파일하고 그냥 아무것도 인쇄되지 프로그램을 실행 한 후 : 여기에 내가 쓴 프로그램입니다. 그래서 syscall 전에 레지스터의 내용을 검사했습니다.

(gdb) info registers 
rax   0x1  1 
rbx   0x4000c5 4194501 
rcx   0x0  0 
rdx   0x6000e4000b  412331802635 ; <-- obviously wrong 
rsi   0x10000 65536 
rdi   0x1  1 
rbp   0x0  0x0 
rsp   0x7fffffffdcc6 0x7fffffffdcc6 

그래서 콜은 프로그램이 모든 바이트를 액세스 할 수 없습니다 때문에 내가 분할 오류의 원인이해야한다고 생각 0x10000에서 시작 412331802635 바이트를 읽을 시도해야합니다.

그러나 아무것도 출력하지 않습니다. 왜? Segmantation Fault가 발생하지 않은 이유는 무엇입니까? 일종의 정의되지 않은 행동 이었나요? 나는 Ubuntu 16.04 LTSintel core i5에 사용하고 있습니다.

+1

'읽기'는 segfault를 발생시키지 않으며 오류를 반환합니다. –

+0

'strace'에서 프로그램을 실행하여 시스템 호출의 args와 반환 값을 디코딩하십시오. asm 디버깅 팁에 대한 자세한 내용은 https://stackoverflow.com/tags/x86/info의 하단을 참조하십시오. –

답변

4

sys_write은 segfault를 발생시키지 않고 단지 오류 코드를 반환합니다. syscall 완료 후 rax에 표시되어야합니다. 참고 사항 : man 2 write

+0

그냥 시도하고'렉스 0xfffffffffffffff2 -14'있어. 이제 이해, 감사합니다. –