mq_receive 在 NASM 中给出“消息太长”错误
Posted
技术标签:
【中文标题】mq_receive 在 NASM 中给出“消息太长”错误【英文标题】:mq_receive gives "Message too long" error in NASM 【发布时间】:2020-07-19 01:59:59 【问题描述】:下面的 NASM 代码是一个更大程序的非常简化的版本。它是共享对象,而不是 .exe;它的入口点是 Main_Entry_fn。它使用 POSIX 消息队列。该程序在两个内核上运行。第一个核心调用“Write_Data_To_Memory_fn”部分,它在其中接收和处理消息。第二个核心调用部分“While_Loop_Test_fn”,它在其中处理数据并发送消息。
就本示例而言,核心实例化已被删除,因为“While_Loop_Test_fn”部分(包括 mq_send)已被绕过——首先我需要设置 mq_receive 以准备接收消息。
消息队列已成功创建,并在“Write_Data_To_Memory_fn”部分成功打开,但问题是 mq_receive 失败并显示消息“消息太长”。
消息长度在属性结构的 mq_msgsize 节点中定义为 656 字节。 MQ_Receive_Buffer 定义为 656 个字节的 82 个四字。传递给 mq_receive 的第三个参数也是 656 字节。
http://man7.org/linux/man-pages/man3/mq_receive.3.html 的 Linux 手册页说:“msg_len 参数指定 msg_ptr 指向的缓冲区的大小;这必须大于或等于队列的 mq_msgsize 属性。”在这里,所有对输出缓冲区的引用都是 656 字节。
这是 NASM 代码:
; Header Section
[BITS 64]
[default rel]
global Main_Entry_fn
global While_Loop_Test_fn
global Write_Data_To_Memory_fn
extern mq_open, mq_close, mq_unlink, mq_send, mq_receive, mq_getattr, perror
%define O_RDONLY 00000000
%define O_WRONLY 00000001
%define O_RDWR 00000002
%define O_CREAT 00000100
section .data align=16
vector_of_8s: times 82 dq 0
MQ_Name: db "/MQ_01",0x00
MQ_FDes: dq 0
MQ_FDes_Core: dq 0
MQ_FDes_Core_02: dq 0
MQ_Receive_Buffer: times 82 dq 0
msg_priority: dq 0
perror_msg: db "Error Number\n"
struc mq_attr
.mq_flags: resd 1
.mq_maxmsg: resd 1
.mq_msgsize: resd 1
.mq_curmsgs: resd 1
endstruc
mq_attributes:
istruc mq_attr
at mq_attr.mq_flags, dd O_RDWR
at mq_attr.mq_maxmsg, dd 100
at mq_attr.mq_msgsize, dd 656
at mq_attr.mq_curmsgs, dd 0
iend
; __________
section .text
Init_Cores_fn:
; __________
; Set up POSIX message queue
Message_queue:
mov rax,O_RDWR
mov rbx,O_CREAT
or rax,rbx
mov rdi,MQ_Name
mov rsi,rax
mov rdx,777 ; mode
mov rcx,mq_attr
call mq_open wrt ..plt
mov [MQ_FDes],rax
jmp Write_Data_To_Memory_fn
; ______________________________________
While_Loop_Test_fn:
; This section is bypassed for the MCRE example
; It is included here to show how messages are sent with
mq_send
Open_message_queue:
lea rdi,[MQ_Name]
mov rsi,O_RDWR
call mq_open wrt ..plt
mov [MQ_FDes_Core],rax
; IPC MESSAGE IS SENT HERE
mov rsi,vector_of_8s ; MQ_Message
mov [rsi+80],rbx ;core number
mov rdi,[MQ_FDes_Core]
mov rsi,MQ_Receive_Buffer
mov rax,199
mov [rsi],rax
mov rdx,96
mov rcx,msg_priority
call mq_send wrt ..plt
; __________
label_900:
; Close message queue
mov rdi,[MQ_FDes]
call mq_close wrt ..plt
lea rdi,[MQ_Name]
call mq_unlink wrt ..plt
ret
; __________
; Main Entry
Main_Entry_fn:
push rdi
push rbp
push rbx
call Init_Cores_fn
pop rbx
pop rbp
pop rdi
ret
;__________
Write_Data_To_Memory_fn:
lea rdi,[MQ_Name]
mov rsi,O_RDONLY
mov rdx,777
mov rcx,mq_attr
call mq_open wrt ..plt
mov [MQ_FDes_Core_02],rax
mov rdi,[MQ_FDes_Core_02]
mov rsi,MQ_Receive_Buffer
mov rdx,656
mov rcx,msg_priority
call mq_receive wrt ..plt ; MQ CALL
cmp rax,-1
jne no_error
mov rdi,perror_msg
call perror wrt ..plt
no_error:
jmp label_900
ret
由于对消息缓冲区大小的所有引用都相同,为什么我会收到错误消息“消息太长”。
感谢您的任何想法。
【问题讨论】:
【参考方案1】:mq_attr 结构的手册页显示结构中的字段都是长整数,您将它们定义为 dd,如果 dq 为 8 个字节,则为 4 个字节,那么这些应该是 8 个字节而不是 4 个字节吗?你没有说你在什么架构上运行它,所以 4 个字节可能是正确的。
【讨论】:
将 struc 元素更改为 dq 后,我现在可以在 rax 而不是 eax 中访问 struc 元素,但是当我调用 mq_receive 时仍然出现“消息太长”错误。以上是关于mq_receive 在 NASM 中给出“消息太长”错误的主要内容,如果未能解决你的问题,请参考以下文章