NASM 分配 returns NULL
NASM malloc returns NULL
在我尝试学习 NASM 的过程中,我尝试创建一个基本程序来测试 malloc
功能。我已经把它贴在下面了:
bits 64
extern malloc
section .data
ARRAY_SIZE: equ 27
array: dq 1
error_message: db "Malloc returned NULL!", 10
error_message_length: equ $ - error_message
section .text
global _start
_start:
; try to allocate an array of bytes in the heap memory using malloc
push dword ARRAY_SIZE
call malloc
;; if malloc returned NULL, throw an error
cmp rax, 0
je err_out
mov [array], eax ; save a pointer to the allocated memory in array
; fill the array with numbers equal to the indices at that location
fill_for:
xor edx, edx ; use edx for the for loop index
.for_start:
cmp edx, ARRAY_SIZE ; break if edx >= BUFFER_SIZE
jg .for_end
mov [array + edx], edx ; array[i] = i;
inc edx
.for_end:
; print the numbers in array
print_for:
xor edx, edx ; use edx for the for loop index
.for_start:
cmp edx, ARRAY_SIZE ; break if edx >= BUFFER_SIZE
jg .for_end
mov eax, [array + edx] ; print array[i]
call print_small_number
.for_end:
print_small_number:
; allocate stack space for the two-digit number string (two digit chars + '[=12=]' = 3b)
;; save the old rbp
mov [rbp], rsp
sub rsp, 8
mov rbp, rsp
;; allocate space for the number string
sub rsp, 3
;; save rdx for the main function
sub rsp, 8
mov [rbp + 3], rdx
; turn the (assumed two-digit in base 10) number into a string in number_string
;; initialize the number to 0x30, 0x30, 0 (0x30 is the offset to turn a number into a base-10 digit; 10 = '\n')
mov byte [rbp], 0x30
mov byte [rbp + 1], 0x30
mov byte [rbp + 2], 10
; the number to print is already in eax
mov bl, 10 ; divide the message length string by 10 to separate the 10s and 1s digits
div bl ;; the quotient is the 10s digits and the remainder is the 1s
add [rbp], al ; move the resulting char into the first slot in number_string
add [rbp + 1], ah ; move the resulting 1s digit char into the second slot in number_string
; print the message length string
mov eax, 4
mov ebx, 1
mov rcx, rbp ; the string starts at rbp
mov edx, 3 ; two digits + [=12=] = 3 chars = 3b
int 0x80
; return
;; restore the old rdx for the main function
mov rdx, [rbp + 3]
add rsp, 8
;; deallocate the number string
add rsp, 3
;; restore the old rbp
add rsp, 8
mov rbp, [rsp]
ret
err_out:
; print error_message
mov eax, 4
mov ebx, 1
mov ecx, error_message
mov edx, error_message_length
int 0x80
; end the program
mov ebx, 0
mov eax, 1
int 0x80
但是,当我从这个基本 NASM 程序调用 malloc
时,它是 returning NULL (0),打印出以下消息:
Malloc returned NULL!
我运行我在一台有 6GB RAM 的笔记本电脑上运行这个,几乎没有其他应用程序打开,我只试图分配 27 个字节,所以 运行内存不足似乎不太可能。
我知道如果给定的大小参数为负数,它可能 return NULL,但正如您在代码中看到的那样,情况并非如此。
有人有什么建议吗?我不明白为什么这个 malloc 调用可以 return NULL。
编辑:
此示例是在 64 位 Linux Mint 17 Qiana 中组装和 运行 自 BASH 脚本以来使用以下命令:
nasm -f elf64 ".asm" -l ".lst" &&
ld -s -o "" ".o" -lc &&
./""
malloc()
的参数应该进入 rdi
,而不是压入堆栈。它可能会失败,因为您正在传递它 0
,或者一些非常高的数字。
另外:
mov [array], eax
应该是:
mov array, rax
因为 malloc()
非常有能力返回一个不适合四个字节的地址,并且因为 array
在那个时候不包含有效的内存地址,所以你应该'不要间接通过它。
在我尝试学习 NASM 的过程中,我尝试创建一个基本程序来测试 malloc
功能。我已经把它贴在下面了:
bits 64
extern malloc
section .data
ARRAY_SIZE: equ 27
array: dq 1
error_message: db "Malloc returned NULL!", 10
error_message_length: equ $ - error_message
section .text
global _start
_start:
; try to allocate an array of bytes in the heap memory using malloc
push dword ARRAY_SIZE
call malloc
;; if malloc returned NULL, throw an error
cmp rax, 0
je err_out
mov [array], eax ; save a pointer to the allocated memory in array
; fill the array with numbers equal to the indices at that location
fill_for:
xor edx, edx ; use edx for the for loop index
.for_start:
cmp edx, ARRAY_SIZE ; break if edx >= BUFFER_SIZE
jg .for_end
mov [array + edx], edx ; array[i] = i;
inc edx
.for_end:
; print the numbers in array
print_for:
xor edx, edx ; use edx for the for loop index
.for_start:
cmp edx, ARRAY_SIZE ; break if edx >= BUFFER_SIZE
jg .for_end
mov eax, [array + edx] ; print array[i]
call print_small_number
.for_end:
print_small_number:
; allocate stack space for the two-digit number string (two digit chars + '[=12=]' = 3b)
;; save the old rbp
mov [rbp], rsp
sub rsp, 8
mov rbp, rsp
;; allocate space for the number string
sub rsp, 3
;; save rdx for the main function
sub rsp, 8
mov [rbp + 3], rdx
; turn the (assumed two-digit in base 10) number into a string in number_string
;; initialize the number to 0x30, 0x30, 0 (0x30 is the offset to turn a number into a base-10 digit; 10 = '\n')
mov byte [rbp], 0x30
mov byte [rbp + 1], 0x30
mov byte [rbp + 2], 10
; the number to print is already in eax
mov bl, 10 ; divide the message length string by 10 to separate the 10s and 1s digits
div bl ;; the quotient is the 10s digits and the remainder is the 1s
add [rbp], al ; move the resulting char into the first slot in number_string
add [rbp + 1], ah ; move the resulting 1s digit char into the second slot in number_string
; print the message length string
mov eax, 4
mov ebx, 1
mov rcx, rbp ; the string starts at rbp
mov edx, 3 ; two digits + [=12=] = 3 chars = 3b
int 0x80
; return
;; restore the old rdx for the main function
mov rdx, [rbp + 3]
add rsp, 8
;; deallocate the number string
add rsp, 3
;; restore the old rbp
add rsp, 8
mov rbp, [rsp]
ret
err_out:
; print error_message
mov eax, 4
mov ebx, 1
mov ecx, error_message
mov edx, error_message_length
int 0x80
; end the program
mov ebx, 0
mov eax, 1
int 0x80
但是,当我从这个基本 NASM 程序调用 malloc
时,它是 returning NULL (0),打印出以下消息:
Malloc returned NULL!
我运行我在一台有 6GB RAM 的笔记本电脑上运行这个,几乎没有其他应用程序打开,我只试图分配 27 个字节,所以 运行内存不足似乎不太可能。
我知道如果给定的大小参数为负数,它可能 return NULL,但正如您在代码中看到的那样,情况并非如此。
有人有什么建议吗?我不明白为什么这个 malloc 调用可以 return NULL。
编辑:
此示例是在 64 位 Linux Mint 17 Qiana 中组装和 运行 自 BASH 脚本以来使用以下命令:
nasm -f elf64 ".asm" -l ".lst" &&
ld -s -o "" ".o" -lc &&
./""
malloc()
的参数应该进入 rdi
,而不是压入堆栈。它可能会失败,因为您正在传递它 0
,或者一些非常高的数字。
另外:
mov [array], eax
应该是:
mov array, rax
因为 malloc()
非常有能力返回一个不适合四个字节的地址,并且因为 array
在那个时候不包含有效的内存地址,所以你应该'不要间接通过它。