基本汇编功能出现内存错误

问题描述 投票:0回答:1

我是组装初学者,正在参加在线速成课程。本课程的最后挑战之一是函数编写和调用。我的想法是重新创建这个函数:


  str_lower(src_addr):
    i = 0
    if src_addr != 0:
      while [src_addr] != 0x00:
        if [src_addr] <= 0x5a:
          [src_addr] = foo([src_addr])
          i += 1
        src_addr += 1
    return i

其中 src_addr 包含在 rdi 中,i 是 rax。 rdi 将被随机赋予一个值,并且 [rdi] 包含一个字节的信息。函数 foo 包含在 0x403000 处。以下是我重新创建该函数的汇编代码:


.intel_syntax noprefix
jmp _start
str_lower:
    xor rax, rax
    pop rbx
    mov rdi, [rsp]
    cmp rdi, 0
    jnz if
    jmp return
    if:
        cmp byte ptr [rdi], 0x0
        jnz while
        jmp return
        while:
            cmp byte ptr [rdi], 0x5a
            ja increment
            innerif:
                mov rcx, [rdi]
                push rcx
                call 0x403000
                pop rcx
                mov [rdi], cl
                inc rax
            increment:
                cmp byte ptr [rdi], 0
                inc rdi
                jnz while
    return:
        push rax
        push rbx
        ret
_start:
push rdi
call str_lower
pop rax

抱歉,如果代码有点混乱,但希望它是可读的。我的问题是代码编译,但是当我将其传递到应该检查我的挑战的文件中时,传递 rdi 值,并给我我的标志,它给我错误“您的程序已崩溃!无效的内存获取(UC_ERR_FETCH_UNMAPPED)” 。该程序一直循环,直到 rax 和 rdi 非常大,这就是它崩溃的原因,我只是没有理由让它永远循环。我已经检查并更改了这段代码大约 4 个小时,我很迷失这是我最后的手段,哈哈。

我是函数的初学者,所以我的程序已经解决了很多问题,但到目前为止,我已经尝试将 cmp 行中 [rdi] 的指针头更改为“byte ptr”而不是“dword ptr”,老实说,我处于完整状态不知道为什么会这样,但我确信这是一个简单的修复方法。

assembly x86-64
1个回答
0
投票

while
循环结束时,您将得到以下序列:

cmp byte ptr [rdi], 0
inc rdi
jnz while

inc
rdi
影响
ZF
标志,所以你总是会跳回到循环的开头,直到程序崩溃。更改为:

inc rdi
cmp byte ptr [rdi], 0
jnz while

确保您正在测试字符串的末尾。

您还有一些序列,例如:

cmp byte ptr [rdi], 0x0
jnz while
jmp return

标签跳转到的地方就是下一条指令。通过将其更改为:

,您的代码可能会读得更好:
cmp byte ptr [rdi], 0x0
jz return
© www.soinside.com 2019 - 2024. All rights reserved.