【问题标题】:Finding escape characters in AT&T x86 assembly在 AT&T x86 程序集中查找转义字符
【发布时间】:2013-05-08 19:07:55
【问题描述】:

问题1:我有如下汇编代码,其目的是循环输入字符串,并计算它遇到的转义字符'%'的数量:

.globl sprinter

.data

.escape_string: .string "%"

.num_escape: .long 0

.num_characters: .long 0

.text

sprinter:
    pushl %ebp
    movl %esp,%ebp

    movl 8(%ebp),%ecx # %ecx = parameter 1

loop:
    cmpb $0, (%ecx) # if end of string reached
    jz exit
    cmpl $.escape_string,(%ecx) # if escape character found
    je increment
    back:
        incl .num_characters
        incl %ecx
        jmp loop

increment:
    incl .num_escape
    jmp back # jump to 'back'

exit:
    movl .num_escape, %eax # return num_escape

    popl %ebp
    ret

此汇编代码与以下 C 代码一起编译:

#include <stdio.h>
extern int sprinter (char* string);
int main (void)
{
    int n = sprinter("a %d string of some %s fashion!");
    printf("value: %d",n);
    return 0;
}

运行此代码的预期输出是value: 2(因为字符串中有两个'%'字符),但它返回value: 0,这意味着以下行失败(因为它从不增加计数器):

cmpl $.escape_string,(%ecx) # if escape character found

我是否使用了错误的字符串比较方法?外部循环工作正常,并且 .num_characters 正确包含我的字符串中的字符数。我为一个简单的 C 程序生成了一些汇编代码,该程序将字符串“hello”与“hello2”进行了比较,这是相关代码:

.LC0:
    .string "hello"
.LC1:
    .string "hello2"

...
movl    $.LC0, -4(%ebp)
cmpl    $.LC1, -4(%ebp)

看起来和我试过的很相似,不是吗?

问题 2。这段代码是用汇编语言编写的简化 sprintf 函数的一部分。这意味着第一个参数应该是结果字符串,第二个参数是格式。如何将字节字符从一个寄存器中的当前位置复制到另一个寄存器中的当前位置?假设我们已将参数分配到两个寄存器中:

movl 8(%ebp),%edx # %edx = result-string
movl 12(%ebp),%ecx # %ecx = format-string

我在循环中尝试了以下操作:

movb (%ecx), %al
movb %al, (%edx) # copy current character to current position in result register
incl %ecx
incl %edx

但结果字符串只包含a(我的字符串中的第一个字符),而不是我预期的完整字符串。

感谢所有帮助,因为这个比较问题(问题 1)目前让我陷入困境。

【问题讨论】:

    标签: string gcc assembly character match


    【解决方案1】:

    关于问题 1,您似乎在比较单字节字符,因此在检查转义字符时“cmpl”应该是“cmpb”。您还需要将角色加载到寄存器中。我对 AT&T 组装不是很熟悉,所以我希望这是正确的。

    循环前:

    movb .escape_string, %al
    

    比较:

    cmpb %al, %(ecx)
    

    【讨论】:

    • 这返回:/tmp/ccZauarM.o: In function 'loop': (.text+0xd): relocation truncated to fit: R_386_8 against '.data' collect2: error: ld returned 1 exit status 这让我相信该字符串实际上存储为一个 long 并且它正在截断字符串以使其适合字节比较,这是对错误?
    • 我相信 .escape_string 指的是文字字符串的地址。您需要将角色加载到字节寄存器中。
    • 将其移入字节寄存器,然后进行比较,效果很好!谢谢!
    • 酷。我不确定我在答案中输入的代码在 AT&T 的语法上是否正确。如果它处于关闭状态,您可能需要进行编辑。
    • 您的第一个编辑是正确的并且对我有用,即movb .escape_string, %al,我无法编辑它,因为它编辑的字符少于 6 个。
    猜你喜欢
    • 1970-01-01
    • 2013-06-30
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 2019-04-04
    • 1970-01-01
    相关资源
    最近更新 更多