Linux mov edx覆盖cx寄存器

Linux mov edx覆盖cx寄存器,linux,assembly,nasm,Linux,Assembly,Nasm,我试着把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 0

我试着把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上编译


谢谢

你看错了。问题是“mov ecx,msg”。ECX是扩展寄存器,CX是它的下半部分,所以您在它上面写


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

您看错了行。问题是“mov ecx,msg”。ECX是扩展寄存器,CX是它的下半部分,所以您在它上面写


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

您看错了行。问题是“mov ecx,msg”。ECX是扩展寄存器,CX是它的下半部分,所以您在它上面写


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

您看错了行。问题是“mov ecx,msg”。ECX是扩展寄存器,CX是它的下半部分,所以您在它上面写

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

此代码修复了它:

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
将该值移动到变量中,然后将其解算,然后将其放回原处

此代码修复了该值:

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
将该值移动到变量中,然后将其解算,然后将其放回原处

此代码修复了该值:

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
将该值移动到变量中,然后将其解算,然后将其放回原处

此代码修复了该值:

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

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

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