Код 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 определен как 82 четырехсловных слова для 656 байтов. Третий параметр, передаваемый в mq_receive, также составляет 656 байт.
Страница man Linux в http://man7.org/linux/man-pages/man3/mq_receive.3.html говорит: «Аргумент 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
Поскольку все ссылки на размер буфера сообщений одинаковы, почему я получаю сообщение об ошибке «сообщение слишком длинное».
Спасибо за любые идеи.