Linux下x86_64汇编无法向Socket服务器发送数据的问题
汇编代码无法向本地4096端口发送数据的问题排查与修复
你的汇编代码存在几个关键问题,导致无法成功发送数据,以下是问题点和修复方案:
问题点
- 入口点定义错误:Linux x86_64汇编程序的标准入口点是
_start,但你的代码声明global socket并以socket:作为起始标签,链接器无法找到正确的程序入口,执行流程会异常。 - 文件描述符存储空间不足:
sock_fd: resb 4仅分配4字节存储socket文件描述符,但x86_64平台下rax寄存器是8字节,直接存储会截断数据,后续connect和sendto会使用错误的文件描述符。 - connect系统调用参数错误:
connect的第三个参数要求传入sockaddr结构的长度,你的代码传入了1024,而实际struct sockaddr_in的长度是16字节,这会导致系统调用失败。
修复后的代码
section .bss sock_fd: resb 8 ; 分配8字节存储64位文件描述符 section .data msg: db "Hello World",0 len equ $ - msg ; struct sockaddr_in 结构,网络字节序 struct: dw 2 ; sin_family = AF_INET(2) db 0x10, 0x00 ; sin_port = 4096 (0x1000,大端序) db 0x7f, 0x00, 0x00, 0x01 ; sin_addr = 127.0.0.1 times 8 db 0 ; sin_zero 填充 section .text global _start ; 声明正确的程序入口点 _start: ; 创建socket mov rax, 41 ; sys_socket的系统调用号 mov rdi, 2 ; AF_INET mov rsi, 1 ; SOCK_STREAM mov rdx, 0 ; protocol=0 syscall mov [sock_fd], rax ; 存储8位文件描述符 ; 连接服务器 mov rax, 42 ; sys_connect的系统调用号 mov rdi, [sock_fd] mov rsi, struct mov rdx, 16 ; sockaddr结构长度为16字节 syscall ; 发送数据 mov rax, 44 ; sys_sendto的系统调用号 mov rdi, [sock_fd] mov rsi, msg mov rdx, len mov r8, struct mov r9, 16 syscall ; 退出程序 mov rax, 60 xor rdi, rdi ; 退出码0 syscall
额外说明
- 修复后的代码给socket调用添加了
rdx,0,显式传入默认协议0,更符合规范。 - 退出时用
xor rdi,rdi设置退出码为0,确保程序正常退出。 - 建议在每个系统调用后添加错误检查逻辑:判断
rax是否小于0,若小于则跳转到错误处理分支,避免调用失败后继续执行无效操作。
内容的提问来源于stack exchange,提问作者Raych
相关产品推荐
相关产品推荐

