0

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

.data 部分:

.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

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

4

1 回答 1

0

您使用的数据是 32 位,如偏移量相隔 4 个字节所示,但您以 64 位访问它。如果你以十六进制打印 429496729600,你会得到 0x6400000000,这表明低 32 位都是 0。

要解决此问题,请将您的数据字段更改为 64 位宽,或者通过将q后缀更改为ls 并将寄存器更改为 32 位访问,e而不是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
于 2013-03-12T02:41:51.643 回答