【问题标题】:x86 Assembly ATT/GNU Syntax Print String Subroutinex86 汇编 ATT/GNU 语法打印字符串子例程
【发布时间】:2014-05-05 02:16:15
【问题描述】:

我正在尝试创建一个子例程,允许用户使用 ASCII 缓冲区加载寄存器并通过调用子例程将其打印到屏幕上。

我猜我用于递增 %edi(计数器)的 while 循环没有看到终止字符。

我也想知道我是否使用了正确的寻址模式(我在 while 循环中使用了间接寄存器)。

.data

  nts:

    .ascii "This is a string.\0"


.text

  .global _start

  .include "print.asm"

  _start:

    mov $ntstring, %ebx

    call PrintString
    mov $1, %eax



    int $0x80

这是我的包含文件:

PrintString:
        push  %ebp              
        :      

        cmp $0, (%ebx,%edi) #i am trying to do a while loop that increments edi until
                            #it encounters the null terminator "\0"
        je Print

        add   $1,  %edi         

        jmp StringNotEmpty

【问题讨论】:

  • 我不认为 \0 是一个有效的 NULL 终止符。那或者你的 cmp 是错误的。
  • 是的,它是 cmp。我应该使用 cmpb。感谢您的意见。

标签: assembly x86 32-bit inline-assembly


【解决方案1】:

正如您所注意到的,问题出在您对 NUL 终止符的检查中:

cmp $0, (%edx,%edi)

在 32 位上,默认操作数大小是 32 位字,因此您需要以 4× \0 结束字符串以使其停止(或者幸运地遇到零填充你的字符串后面的垃圾)。

在这种情况下,您只想加载和检查一个 8 位字符,因此您需要像这样使用b 后缀:

cmpb $0, (%edx,%edi)

你可以看到所有不同的后缀here

【讨论】:

  • 现在完美运行。非常感谢!我仍在学习,我知道 MOV 的不同后缀,但我没有将它们用于所有操作码,而不仅仅是 MOV。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-15
  • 1970-01-01
  • 2013-02-01
相关资源
最近更新 更多