eax 与其他寄存器相比的不同行为

发布于 2024-10-09 10:17:09 字数 1175 浏览 0 评论 0原文

我编写了一个小的汇编代码片段(Gas,32 位),它接受命令行参数,计算其字符并打印字符串(如果它具有一定的长度)(仅用于调试目的)。我对汇编比较陌生,所以我很确定我在这里错过了一些东西,因为当我将字符串存储在 eax 中时,与 ecx、edx 或 esi 等相比,我会得到不同的行为。

这是片段。当您用 eax 替换 esi 时,无论字符串有多长,循环都只会进入两次,因此计数器 (ebx) 始终为 1。使用 esi 或其他寄存器,一切似乎都工作正常。

.section .text
.globl _start
_start:
    movl    %esp, %ebp
    movl    0(%ebp), %eax   # get argc
    cmpl    $2, %eax        # ensure argc == 2
    jne     _exit           
    movl    8(%ebp), %eax   # get argv[1]
    movl    $0, %ebx        # set counter to 0
_begin_loop:
    movb    (%eax), %al     # load a character into %al
    cmpb    $0, %al         # see if \0 is reached
    je      _end_loop       # exit loop if at end of string
    incl    %ebc            # increment counter
    incl    %eax            # advance string
    jmp     _begin_loop
_end_loop:
    cmpl    $6, %ebx        # print the string if it's six characters long
    jne     _exit
    movl    $4, %eax        # prepare for output
    movl    $1, %ebx
    movl    8(%ebp), %ecx)
    movl    $6, %edx
    int     0x80
_exit:
    movl    $1, %eax
    movl    $0, %ebx
    int     0x80

有人可以给我一个关于我做错/误解的提示吗?

问候

I've written a small assembly snippet (Gas, 32 bit) that takes a command-line argument, counts its characters and prints the string if it has a certain length (just for debugging purposes). I'm relatively new to assembly, so I'm pretty sure there is something I miss here because I get different behaviour when I store the string in eax compared to, for instance, ecx, edx or esi.

Here is the snippet. When you replace esi with eax, the loop is entered only twice no matter how long the string is, hence the counter (ebx) is always 1. With esi or other registers, everything seems to work fine.

.section .text
.globl _start
_start:
    movl    %esp, %ebp
    movl    0(%ebp), %eax   # get argc
    cmpl    $2, %eax        # ensure argc == 2
    jne     _exit           
    movl    8(%ebp), %eax   # get argv[1]
    movl    $0, %ebx        # set counter to 0
_begin_loop:
    movb    (%eax), %al     # load a character into %al
    cmpb    $0, %al         # see if \0 is reached
    je      _end_loop       # exit loop if at end of string
    incl    %ebc            # increment counter
    incl    %eax            # advance string
    jmp     _begin_loop
_end_loop:
    cmpl    $6, %ebx        # print the string if it's six characters long
    jne     _exit
    movl    $4, %eax        # prepare for output
    movl    $1, %ebx
    movl    8(%ebp), %ecx)
    movl    $6, %edx
    int     0x80
_exit:
    movl    $1, %eax
    movl    $0, %ebx
    int     0x80

Can anybody give me a hint about what I'm doing wrong/misunderstanding?

Greets

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

辞取 2024-10-16 10:17:09

al 寄存器实际上是 eax 寄存器的最低 8 位。因此,指令 movb (%eax), %al 破坏了 eax 的最低 8 位,即您的指针。

作为一般建议,学习使用调试器单步调试代码并找出计算机执行与您期望不同的操作的地方。

编辑:发布的代码中存在一些微不足道的语法错误(例如 ebc 而不是 ebx),但我假设存在一些复制错误,因为您说否则它可以工作。

The al register is really the lowest 8 bits of the eax register. So, the instruction movb (%eax), %al destroys the lowest 8 bits of eax, that is your pointer.

As a general advice, learn to use a debugger to step through your code and spot where the computer does something different from what you expect.

EDIT: there are some trivial syntax errors in the posted code (such as ebc instead of ebx), but I assume some copying error since you say otherwise it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文