反转字符串并在 IA32 程序集中打印

Posted

技术标签:

【中文标题】反转字符串并在 IA32 程序集中打印【英文标题】:Reversing a string and printing it in IA32 assembly 【发布时间】:2015-05-31 23:03:55 【问题描述】:

所以基本上我是在尝试读取一个字符串,增加一个计数器(在本例中为 %edx),直到我读取到一个 \n,然后,反向打印它。

这是我的代码:

.section .data
cadsal: 
    .asciz "Por favor ingrese su cadena:\n"

leer:
    .asciz "%s"

salidafinal:
    .asciz "La cadena introducida, invertida es:\n"

imp:
    .asciz "%c\n"

.section .bss .comm cadena,50,1

.section .text

.globl _start

_开始:

leal cadsal, %eax
pushl %eax
call printf
addl $4, %esp

leal cadena, %eax
pushl %eax
leal leer, %eax
pushl %eax  
call scanf
addl $8, %esp

xorl %edx, %edx

剧情:

movb cadena(%edx), %al
incl %edx
cmpb $0, %al
jne Contar

leal salidafinal, %ecx
pushl %ecx
call printf
addl $4, %esp

addl $-2, %edx

逆变器:

movb cadena(%edx), %al
pushl %eax
leal imp, %ebx
pushl %ebx
call printf
addl $8, %esp

decl %edx
cmpl $0, %edx
jge Invertir

movl $1, %eax
int $0x80

我在编译时使用命令 -nostartfiles。它可以工作,但是当我运行它时,进入“Invertir”时会出现分段错误。我需要帮助来检测这段代码有什么问题。

谢谢!

【问题讨论】:

【参考方案1】:

您的直接问题是 cmpb '\n', %al,它缺少 at&t 语法中所需的 $ 符号以使其立即生效。事实上,'\n' 被认为是一个地址,并且是一个无效的地址。你应该使用cmpb $'\n', %al

但是scanf 根本不会将'\n' 放入缓冲区,因为%s 会在空白处停止。所以你真的想寻找一个终止的零字节,那就是使用cmpb $0, %al。或者,如果您确实需要阅读整行,请改用fgets

如果您解决了这个问题,您将遇到下一个问题,即您在 cmpjne 之间有一个 incl %edx,这将更改标志,因此您将不会根据比较不过是增量。解决方法:交换cmpincl

还有一个问题是一些寄存器,包括%edx,是调用者保存的。因此,它们可以通过调用函数进行修改,您可以使用call printf。你应该 push/pop 围绕这两者来保留价值。

即便如此,在您手动打印最终的\n 之前,由于缓冲,您可能不会看到任何输出。

注意,如果你打算使用 C 库,你真的不应该使用-nostartfiles。相反,您应该使用入口点main 并正常组装和链接。此外,您应该简单地从main(或最多call exit)返回而不使用直接系统调用,因为这不允许C 库正确清理。顺便说一句,这也会刷新 I/O 缓冲区,因此即使没有额外的换行符,您也会看到输出。

你真的应该学会使用调试器。

【讨论】:

嘿!谢谢回答。对不起,我仍然是组装的业余爱好者。你到底是什么意思:你应该推动/弹出这两个以保持价值。我应该推什么? push %edxprintf 业务之前(包括参数设置)和pop %edxadd esp 之后。 交换了第一个 cmp 和 incl,“Contar”现在似乎工作正常。我现在在“Invertir”中遇到分段错误。修改 addl $-2 , %edx 因为 contar 结束时 %edx 从 $0 (字符串结尾)向前迈进了一步。 没关系。学习了一点如何使用调试器。更改了我的代码中的一些内容。那个 pushl/pop 的东西救了我的命。非常感谢。

以上是关于反转字符串并在 IA32 程序集中打印的主要内容,如果未能解决你的问题,请参考以下文章

中缀到前缀的程序中的c函数中未返回反转字符串

在C中打印反转的字符串/数组

如何使用递归反转字符串?

在c中反转字符串数组[重复]

在python中反转字符串中的子字符串

Python使用循环结构编写:输入一个整数,将整数中的数字反转,并在控制打印出来?