【问题标题】:mov edx overwrites cx registermov edx 覆盖 cx 寄存器
【发布时间】:2024-04-28 08:50:02
【问题描述】:

我正在尝试打印 Hi 10 次。这是我的代码。

section .data

msg db "Hi"

section .text

global _start

_start:

    mov cx, 10


    L1:
    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    mov edx, 3
    int 0x80

    dec cx
    jnz L1


    mov eax, 1
    mov ebx, 0
    int 0x80

gdb 报告 mov edx, 3 将 cx 寄存器覆盖为某个疯狂的值,因此循环一直持续下去。

我做错了什么?是因为它们是同一个寄存器吗?

如何用这么少的寄存器进行汇编程序?

用nasm和ld在centos上编译

谢谢

【问题讨论】:

    标签: linux assembly nasm


    【解决方案1】:

    您正在查看错误的行。问题是“mov ecx,味精”。 ECX 是扩展寄存器,CX 是它的下部,所以你要重写它。

    最好将循环计数器保存在堆栈中,因为谁知道'int' 调用可能会改变。在“L1:”之后添加“push cx”(或 ecx)。和 'int' 调用后的 'pop cx' 以保留寄存器的内容。

    【讨论】:

      【解决方案2】:

      这段代码修复了它:

      section .data
      
      msg db "Hi"
      
      counter dw 10
      
      section .text
      
      global _start
      
      _start:
      
      
      
      
          L1:
          mov eax, 4
          mov ebx, 1
          mov ecx, msg
          mov edx, 2
          int 0x80
      
          mov cx, [counter]
          dec cx
          mov [counter], cx   
      
          jnz L1
      
      
          mov eax, 1
          mov ebx, 0
          int 0x80
      

      将值移动到变量中,然后对其进行解码,然后将其放回

      【讨论】:

      • 对于如此少量的代码,并且没有其他对循环计数器的引用,在 L1: 标签之后的 5 条指令周围进行简单的 cx 推送/弹出比保留静态标签更可取存储临时(即“本地”变量)的内存位置。您的解决方案相当于在高级语言中使用“静态”变量。高级语言中的局部变量放在堆栈上,因此内存使用是临时的(使用基指针而不是 push/pop,但本质上是一样的)。