【问题标题】:malloc and pointers in assemblymalloc 和汇编中的指针
【发布时间】:2014-04-28 15:29:55
【问题描述】:

我正在尝试在程序集中实现一个链接列表,所以我有一个“数组”(实际上是 20 个字节)来保存 5 个可能列表的链接。 每个“链接”长度为 5 个字节(1 个用于数据,4 个用于指针 - x86 机器)。 现在我调用 malloc 并创建了 1 个链接并将一个数字推入第一个字节(十进制数)并将链接指针移动到数组的开头。 之后我尝试再次调用 malloc 来创建一个新链接,但是创建的新链接覆盖了我已经推送到数组中的链接,我不知道为什么!!!。 这是代码和一些输入/输出示例:

section .rodata
LC0:
    DB  "The number is: %i", 10, 0  ;  string

LC1:
    DB  "Memory allocation failed!!!", 10, 0    ;  string


section .data
section .bss

numbers_stack:
    RESB    20

link:
    RESB    link_size   

section .text
align 16
global main
extern printf
extern malloc
extern gets
link_size EQU 5

_start:
jmp main 

main:

%macro  mymalloc 2  ;malloc macro
mov edx, %1 ; size to allocate
push edx
call malloc
add esp,4
test eax,eax
jz fail_exit
mov [%2], eax
%endmacro

%macro myprintf 1 ;printing macro
push %1
push LC0
call printf
add esp,8
%endmacro

mymalloc link_size,link
mov byte[link], 44
mov dword[numbers_stack],link

mov eax,0
mymalloc link_size,link ; allocate new link - *at this point the contents are allready overwritten

mov eax,[numbers_stack] ; get pointer to list head from numbers_array[0] into eax
mov edx,0
mov dl,byte[eax]
myprintf edx

输出示例: 它总是会打印出应该打印出'44'的数字'40' 如果我删除第二个 mymalloc 它将按预期打印 44,请帮忙!为什么我明明分配了新内存,它仍然指向旧内存位置?!

【问题讨论】:

    标签: pointers assembly x86 nasm


    【解决方案1】:

    您基本上缺少一层间接性。 malloc 将返回一个存储在 link 中的指针(因此它的大小应该是 4,而不是 link_size)。然后,当您执行mov byte[link], 44 时,您将覆盖此指针,而不是写入分配的内存区域。您需要将指针加载到寄存器中(当然 malloc 已经在 eax 中返回了它)然后取消引用它,例如:

    mov eax, [link]
    mov byte [eax], 44
    

    您还需要在那里调整指针,您根本不需要numbers_stack,列表只有一个head 指针。您可能希望使用常见的既定名称,例如 headnextnode,以便其他人更容易理解您在说什么。

    PS:如果您使用 libc 函数,您应该使用入口点 main 而不是 _start 并链接所有必要的启动对象,以便 libc 有机会正确初始化。你最终应该只使用main 中的ret,或者使用exit 函数而不是exit 系统调用。


    更新:这是一个可能的实现,它分配 2 个列表并打印每个列表的第一个值:

    section .rodata
    LC0:
        DB  "The number is: %i", 10, 0  ;  string
    LC1:
        DB  "Memory allocation failed!!!", 10, 0    ;  string
    
    section .bss
    
    struc node
        .next resd 1
        .value resb 1
    endstruc
    
    list_heads:
        RESD    5
    
    section .text
    global main
    extern printf
    extern malloc
    extern gets
    
    main:
    
    %macro  mymalloc 1  ;malloc macro
    push %1 ; size to allocate
    call malloc
    add esp,4
    test eax,eax
    jz fail_exit
    %endmacro
    
    %macro myprintf 1 ;printing macro
    push %1
    push LC0
    call printf
    add esp,8
    %endmacro
    
    mymalloc node_size
    mov [list_heads], eax
    mov dword [eax + node.next], 0
    mov byte [eax + node.value], 44
    
    mymalloc node_size
    mov [list_heads + 4], eax
    mov dword [eax + node.next], 0
    mov byte [eax + node.value], 11
    
    mov eax, [list_heads] ; get pointer to first list head
    movzx edx, byte [eax + node.value]
    myprintf edx
    
    mov eax, [list_heads + 4] ; get pointer to second list head
    movzx edx, byte [eax + node.value]
    myprintf edx
    

    希望这会有所帮助。

    【讨论】:

    • 我想保存 5 个可能的头指针,如何在没有结构来保存指向列表头的指针的情况下管理所有 5 个列表? ,为什么我要分配 5 大小的链接?我需要 1 个字节的数据 + 4 个用于“下一个”指针
    • 哦,好吧,如果你想要 5 个列表,那么是的,你需要那个。
    • 它仍然无效......我要么遗漏了一些东西,要么我不明白你,我已将代码更改为:mymalloc link_size,link mov eax,[link] mov byte [eax],44 mov [link], eax mov dword[numbers_stack],link ; move list head to numbers_array[0] mymalloc link_size,link ; allocate new link mov eax,[link] mov byte [eax],16 mov [link], eax 但它仍然无法正常工作,我还将link_size 更改为4
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 2013-05-09
    相关资源
    最近更新 更多