我正在学习一些汇编语言。在这样做的过程中,我试图在nasm程序集中编写一个带有TCP套接字的echo客户端/服务器。我已经用各种其他语言(如C和java)完成了套接字编程,并尝试使其在汇编中工作。我找到了几个用汇编编写的服务器代码示例,但没有给客户带来太多好运。
我在这里查看了服务器示例:https://gist.github.com/bobbo/e1e980262f2ddc8db3b8
服务器正常工作,我正在尝试编辑它以将其转换为客户端。
这是我到目前为止所拥有的。似乎无法弄清楚在何处放入连接套接字,发送数据和接收数据的指令。
global _start
;; Data definitions
struc sockaddr_in
.sin_family resw 1
.sin_port resw 1
.sin_addr resd 1
.sin_zero resb 8
endstruc
section .bss
sock resw 2
client resw 2
echobuf resb 256
read_count resw 2
section .data
sock_err_msg db "Failed to initialize socket", 0x0a, 0
sock_err_msg_len equ $ - sock_err_msg
connect_err_msg db "Failed to connect socket", 0x0a, 0
connect_err_msg_len equ $ - connect_err_msg
;; sockaddr_in structure for the address the listening socket binds to
pop_sa istruc sockaddr_in
at sockaddr_in.sin_family, dw 2 ; AF_INET
at sockaddr_in.sin_port, dw 0xce56 ; port 22222 in host byte order
at sockaddr_in.sin_addr, dd 0 ; localhost - INADDR_ANY
at sockaddr_in.sin_zero, dd 0, 0
iend
sockaddr_in_len equ $ - pop_sa
section .text
;; Client main entry point
_start:
;; Initialize socket value to 0, used for cleanup
mov word [sock], 0
;; Initialize socket
call _socket
;; Performs a sys_socket call to initialise a TCP/IP socket.
;; Stores the socket file descriptor in the sock variable
_socket:
mov rax, 41 ; SYS_SOCKET
mov rdi, 2 ; AF_INET
mov rsi, 1 ; SOCK_STREAM
mov rdx, 0
syscall
;; Check if socket was created successfully
cmp rax, 0
jle _socket_fail
;; Store the new socket descriptor
mov [sock], rax
ret
;; Performs sys_close on the socket in rdi
_close_sock:
mov rax, 3 ; SYS_CLOSE
syscall
ret
;; Error Handling code
;; _*_fail loads the rsi and rdx registers with the appropriate
;; error messages for given system call. Then call _fail to display the
;; error message and exit the application.
_socket_fail:
mov rsi, sock_err_msg
mov rdx, sock_err_msg_len
call _fail
;; Calls the sys_write syscall, writing an error message to stderr, then
;; exits
;; the application. rsi and rdx must be loaded with the error message and
;; length of the error message before calling _fail
_fail:
mov rax, 1 ; SYS_WRITE
mov rdi, 2 ; STDERR
syscall
mov rdi, 1
call _exit
;; Exits cleanly, checking if the listening or client sockets need to be
;; closed
;; before calling sys_exit
_exit:
mov rax, [sock]
cmp rax, 0
je .client_check
mov rdi, [sock]
call _close_sock
.client_check:
mov rax, [client]
cmp rax, 0
je .perform_exit
mov rdi, [client]
call _close_sock
.perform_exit:
mov rax, 60
syscall