2015-10-12 93 views
0

我试图打印嗨10次。这是我的代码。mov edx覆盖cx寄存器

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寄存器覆盖为一些疯狂的值,所以循环一直持续下去。

我到底做错了什么?是因为他们是同一个注册吗?

一个程序如何装配这么少的寄存器?

编译在你看错行的CentOS与NASM和LD

感谢

回答

3

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

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

0

此代码修复它:

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 

移动值存入一个变量,然后分解它然后将它放回

+1

对于代码这样的量小,并与循环计数器的任何其它引用,在L1:标签之后的5条指令周围的cx的简单推/拉将比保留静态存储器位置来存储临时(即,'本地'变量)更优选。您的解决方案相当于使用高级语言的“静态”变量。高级语言中的局部变量进入堆栈,以便内存使用是临时的(使用基本指针而不是push/pop,但它本质上是相同的)。 –

+0

谢谢@KenBeckett –