以下C程序调用select()来获取在套接字缓冲区中具有数据的客户端套接字列表(使用UNIX域数据报套接字)。从NASM程序调用时,它需要四个参数。参数fds_array []是在NASM中创建并传递给程序的3元素整数数组。
int select_clientsockets(int nfds, fd_set rfds, int fds_array[], int fd_count){
int fds_ready;
int abc;
fd_count = 3;
FD_ZERO(&rfds);
FD_SET(0,&rfds);
fds_ready = select(3, &rfds, NULL, NULL, 0);
for (int i = 0; i < fd_count; i++){
fds_array[i] = 0;
if (FD_ISSET(i, &rfds)) {
fds_array[i] = 1; }
}
for (int i = 0; i < fd_count; i++){
abc = fds_array[i];
printf("Value of array at %d, is %d\n", i, abc );
}
return 0;
}
数据从NASM以rdi,rsi,rdx和rcx传递。 :
mov rdi,7 ; range of fd #s
lea rsi,[socket_client_fds]
lea rdx,[fds_ready]
mov rcx,3 ; number of open client sockets
call [rel select_clientsockets wrt ..got]
如所写,程序挂起。当我使用gdb逐步执行它时,它会正确执行其计算,并且fds_array中的值符合预期。但是在返回行(返回0)处,gdb报告此:
0x00007ffff720cfed in select_clientsockets (
nfds=<error reading variable: Cannot access memory at address 0xfffffffffffffffc>, rfds=<error reading variable: Cannot access memory at address 0x10>,
fds_array=<error reading variable: Cannot access memory at address 0xfffffffffffffff0>,
fd_count=<error reading variable: Cannot access memory at address 0xffffffffffffffec>) at POSIX_Datagram_Socket.c:139
因此它说不能访问变量nfds,rfds和fds_array。但是我刚刚完成了所有步骤,一切都正确。
我的研究针对该gdb错误消息提出了许多Stack Overflow问题,但它们都是特定于事实的,我没有找到适合这些事实的问题。
感谢您提供有关如何在退出时解决此错误的任何想法。
让我们看看这个电话…
mov rdi,7 ; range of fd #s
lea rsi,[socket_client_fds]
lea rdx,[fds_ready]
mov rcx,3 ; number of open client sockets
call [rel select_clientsockets wrt ..got]
在System V AMD64 ABI中,参数将传入:
似乎您正在传递rfds
,就好像它是一个指针一样。不是。它进入堆栈。
如果是Windows,则将作为指针传递。但是,由于您提到了Unix域套接字,因此听起来好像您没有使用Windows(尽管AF_UNIX
实际上在Windows上可用。)>
如果需要从汇编中调用C函数的帮助,只需使用Godbolt。