почему segmentation fault?
посмотрите перед меткой debug. там вызов функции inet_ntoa. я передаю ей регистр, который int содержит ip адрес клиента. и в этой функции происходит ошибка. но как такое возможно? я же передаю единственный параметр и очищаю на всякий случай rax.
global main
extern socket
extern setsockopt
extern bind
extern listen
extern read
extern perror
extern exit
extern close
extern accept
extern write
extern read
extern inet_ntoa
extern strlen
extern strncpy
extern printf
PF_INET equ 2
SOL_SOCKET equ 1
SO_REUSEPORT equ 15
SOCK_STREAM equ 1
SIZE_SOCKADDR_IN equ 16
section .text
main:
push rbp
mov rbp, rsp
sub rsp, 128
;[rsp + 0] int sock
;[rsp + 4] int optval
;[rsp + 8] char buffer
;[rsp + 24] struct sockaddr_in client
;[rsp + 40] int len of ip
;[rsp + 44] char *ptr
;[rsp + 52] size of struct sockaddr_in
;[rsp + 56] int sock_client
;[rsp + 60] struct sockaddr_in server
xor rax, rax
mov rdi, PF_INET
mov rsi, SOCK_STREAM
mov rdx, 0
call socket
cmp rax, 0
jg set_option_socket_reuse_port
error_socket:
lea rdi, [error_socket_string]
call perror
xor rax, rax
mov rdi, 1
jmp exit_program
set_option_socket_reuse_port:
mov [rsp + 0], eax ; sock
xor rax, rax
xor rdi, rdi
xor rsi, rsi
xor r8, r8
xor rcx, rcx
mov [rsp + 4], dword 1 ; optval
mov edi, [rsp + 0] ; sock
mov esi, SOL_SOCKET
mov edx, SO_REUSEPORT
lea rcx, [rsp + 4] ; optval
mov r8d, 4
call setsockopt
cmp rax, 0
je bind_socket
error_set_option_reuseport:
lea rdi, [error_socket_opt_reuseport]
call perror
jmp exit_program
bind_socket:
xor rax, rax
mov ax, [server_port]
xchg al, ah
mov [rsp + 60 + 2], ax
mov [rsp + 60], word PF_INET
mov [rsp + 60 + 4], dword 0x0100007f;
xor rdi, rdi
mov edi, [rsp + 0] ; sock
lea rsi, [rsp + 60] ; struct sockaddr_in server
xor rdx, rdx
mov edx, SIZE_SOCKADDR_IN
xor rax, rax
call bind
cmp rax, 0
je listen_socket
error_bind_socket:
lea rdi, [error_socket_bind]
call perror
jmp exit_program
listen_socket:
xor rax, rax
xor rdi, rdi
mov edi, [rsp + 0] ; sock
mov rsi, 0
call listen
cmp rax, 0
je accept_client
error_listen_socket:
lea rdi, [error_socket_listen]
call perror
jmp exit_program
accept_client:
xor rdx, rdx
mov edx, [size_msg_accept_client]
lea rsi, [msg_accept_client]
mov rdi, 1 ; sock
xor rax, rax
call write
mov eax, 16
mov [rsp + 52], eax ;
lea rdx, [rsp + 52] ; ptr sizeof sockaddr_in
lea rsi, [rsp + 24] ; ptr sockaddr_in
xor rdi, rdi
mov edi, [rsp + 0] ; sock
xor rax, rax
call accept
cmp rax, 0
jg new_client
error_accept:
lea rdi, [error_socket_accept]
call perror
jmp exit_program
new_client:
mov [rsp + 56], dword eax
xor rdi, rdi
mov edi, dword [rsp + 24 + 4]
xor rax, rax
call inet_ntoa
mov [rsp + 44], rax
xor rdi, rdi
mov rdi, [rsp + 44]
call strlen
inc eax
mov [rsp + 40], eax
xor rax, rax
xor rdx, rdx
mov edx, [rsp + 40]
mov rsi, [rsp + 44]
lea rdi, [rsp + 8]
call strncpy
xor rax, rax
lea rsi, [rsp + 8]
lea rdi, [msg_connect_client]
debug:
call printf
exit_program:
call exit
leave
ret
section .rodata
; -------------- сообщения об ошибках -----------------------
error_socket_string db 'Не удалось открыть сокет', 0x0
error_socket_opt_reuseport db 'Не удалось установить опцию для сокета SO_REUSEPORT', 0x0
error_socket_bind db 'Не удалось привязать сокет', 0x0
error_socket_listen db 'Не удалось задать параметр для прослушивания', 0x0
error_socket_accept db 'Не удалось принять клиента', 0x0
msg_accept_client db 'Ожидание новых клиентов', 0xa, 0x0
size_msg_accept_client dd $ - msg_accept_client
msg_connect_client db 'Подключился клиент: %s', 0xa, 0x0
; -------------- глобальные переменные, которые легко искать ----------
server_port dd 8020
а вот компиляция
all:
nasm -f elf64 server.asm -o server.o
gcc server.o -no-pie -o test
я посмотрел код функции inet_ntoa с помощью objdump -M intel -d /usr/lib/x86_64-linux-gnu/libc-2.31.so | less, и нашел там функцию.
0000000000132aa0 <inet_ntoa@@GLIBC_2.2.5>:
132aa0: f3 0f 1e fa endbr64
132aa4: 41 54 push r12
132aa6: 89 f8 mov eax,edi
132aa8: 41 89 f9 mov r9d,edi
132aab: 4c 8b 25 de 82 0b 00 mov r12,QWORD PTR [rip+0xb82de] # 1ead90 <h_errlist@@GLIBC_2.2.5+0xc70>
132ab2: 0f b6 d4 movzx edx,ah
132ab5: c1 e8 18 shr eax,0x18
132ab8: 40 0f b6 cf movzx ecx,dil
132abc: be 12 00 00 00 mov esi,0x12
132ac1: 64 4c 03 24 25 00 00 add r12,QWORD PTR fs:0x0
132ac8: 00 00
132aca: 41 c1 e9 10 shr r9d,0x10
132ace: 41 89 d0 mov r8d,edx
132ad1: 48 8d 15 bc 75 08 00 lea rdx,[rip+0x875bc] # 1ba094 <_libc_intl_domainname@@GLIBC_2.2.5+0x2c8f>
132ad8: 48 83 ec 08 sub rsp,0x8
132adc: 4c 89 e7 mov rdi,r12
132adf: 45 0f b6 c9 movzx r9d,r9b
132ae3: 50 push rax
132ae4: 31 c0 xor eax,eax
132ae6: e8 f5 23 f3 ff call 64ee0 <__snprintf@@GLIBC_PRIVATE>
132aeb: 58 pop rax
132aec: 4c 89 e0 mov rax,r12
132aef: 5a pop rdx
132af0: 41 5c pop r12
132af2: c3 ret
но что именно не так не могу понять, потому что в отладчике библиотека недосигаема для дизассемблера.