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 中给出“消息太长”错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 nasm 和 qemu 运行引导加载程序的问题

NASM 程序集将输入转换为整数?

尝试访问时带有结构的 C mq_receive() 会导致段错误

Nasm:在 bmp 文件中隐藏 messagem

如何在 NASM 中使用 scanf?

Hello World 在 Windows 程序集中使用 nasm