X86_64从内存地址加载时程序集不返回正确的值

时间:2013-03-12 01:41:01

标签: memory assembly load x86-64 cpu-registers

我是X86_64程序集的新手,我正在尝试实现一个brk内存管理程序,但是我遇到了一些代码行的问题。

.data part:

.section .data

heap_start: .double 0

.equ HDR_AVAIL_OFFSET, 0
.equ HDR_SIZE_OFFSET,4
.equ UNAVAILABLE, 0
.equ AVAILABLE, 1

带有问题的文本部分:

.text
alloc:
    movq heap_start, %rdx
loop:
    movq HDR_AVAIL_OFFSET(%rdx), %rcx
    cmpq $UNAVAILABLE, %rcx
    jne found_space
loop2:
    movq HDR_PROX(%rdx), %rdx
    cmpq %rdx, heap_start
    jne loop
    jmp new_brk
found_space:

    cmpq HDR_SIZE_OFFSET(%rdx), %rdi
    jg loop2

问题是,HDR_AVAIL_OFFSET(%rdx)应该在heap_start上加载由0寻址的内容。但是,它将一个完全不同的内存地址返回到%rcx。

heap_start指向我要检查的内存数组的开头,第一个元素是0。 当我使用x / nfu检查gdb上的内存时,它显示以下内容:

(gdb) x/nfu $rdx
0x602001:  0

但是

之后
movq HDR_AVAIL_OFFSET(%rdx), %rcx

%rcx是:

(gdb) print $rcx
$1 = 429496729600

谁能告诉我我做错了什么? 谢谢。

1 个答案:

答案 0 :(得分:0)

您使用的数据是32位,如偏移量相差4个字节所示,但您将其作为64位进行访问。如果要以十六进制打印429496729600,则会得到0x6400000000,这表示低32位都是0。

要解决此问题,请将数据字段更改为64位宽,或将q后缀更改为l并将寄存器更改为e,以更改为32位访问在处理数据时,而不是r

.text
alloc:
    movq heap_start, %rdx               # Address, 64 bits
loop:
    movl HDR_AVAIL_OFFSET(%rdx), %ecx   # Data, 32 bits
    cmpl $UNAVAILABLE, %ecx             # Data
    jne found_space
loop2:
    movq HDR_PROX(%rdx), %rdx           # Address
    cmpq %rdx, heap_start               # Address
    jne loop
    jmp new_brk
found_space:
    cmpl HDR_SIZE_OFFSET(%rdx), %edi    # Data
    jg loop2