这是有点古怪,但我闲逛与GNU汇编今天(我希望能够至少阅读的语法),并试图获得这一点做作的例的排雷工作。即我只是想去从0到100、印刷出的数字所有的时间。因此,几分钟后我来了这个:

# count.s: print the numbers from 0 to 100. 
    .text
string: .asciz "%d\n"
    .globl _main

_main:
    movl    $0, %eax # The starting point/current value.
    movl    $100,   %ebx # The ending point.

_loop:
    # Display the current value.
    pushl   %eax
    pushl   $string
    call     _printf
    addl     $8, %esp

    # Check against the ending value.
    cmpl    %eax, %ebx
    je    _end

    # Increment the current value.
    incl    %eax
    jmp _loop   

_end:

所有我从这是3印刷一遍又一遍。就像我说的,只是一点点做作的例子,所以不要太担心,它不是一个生死攸关的问题。

(格式是一个有点搞砸了,但没什么大不了的).

有帮助吗?

解决方案

你不能相信什么,任何所谓程序不会对任何登记册。无论是推动登记册栈和弹出他们的背后叫printf或有所增加和终点值保持在存和读写入注册为你需要他们。

我希望以下工作的。我假设pushl有equivalant popl和你可以把一个额外的几个数字到堆。

# count.s: print the numbers from 0 to 100. 
    .text
string: .asciz "%d\n"
    .globl _main

_main:
    movl    $0, %eax # The starting point/current value.
    movl    $100,       %ebx # The ending point.

_loop:
    # Remember your registers.
    pushl   %eax
    pushl   %ebx

    # Display the current value.
    pushl   %eax
    pushl   $string
    call     _printf
    addl     $8, %esp

    # reinstate registers.
    popl   %ebx
    popl   %eax

    # Check against the ending value.
    cmpl    %eax, %ebx
    je    _end

    # Increment the current value.
    incl    %eax
    jmp _loop   

_end:

其他提示

我不太熟悉_printf,但它可能是它修改eax?Printf应的回报的数字印刷,在这种情况下是两个:'0'和' '。我认为这返回这eax,当你增加它,你得到3,这是什么你进行打印。你可能会更好使用不同的登记柜台上。

你可以安全地使用登记册,是"被叫保存",而不具有拯救他们自己。在x86这些是电子数据交换,esi,并ebx;其他体系结构有更多的。

这些都记录在《参考文献: http://math-atlas.sourceforge.net/devel/assembly/

写得很好的功能通常会把所有注册栈和出他们的时候他们这样做,他们仍然保持不变的期间的功能。唯一的例外将是eax包含返回值。图书馆的功能,如printf是最有可能编写这种方式,所以我不会做,因为楔建议:

你会需要这样做对任何其他变量。使用寄存器储存地的变量是相当多的保留体系结构有足够的注册,以支持它的(例如史诗,amd64,等等。)

事实上,从我所知道的,编译器通常编制职能的方式来处理正是这个问题。

@seanyboy,你的解决方案是大材小用。所有需要的是更换eax与其他一些寄存器等ecx.

内森是在正确的轨道。你不能想当然地认为登记册的价值将会未经修改后呼吁一个子程序。事实上,这是最好的假设他们将被修改,其他的子程序不能够做到这一点的工作(至少对低寄存器计体系结构等x86).如果你想要保留一个值应储存在存储器(例如把它推到叠,并跟踪它的位置)。

你会需要这样做对任何其他变量。使用寄存器储存地的变量是相当多的保留体系结构有足够的注册,以支持它的(例如史诗,amd64,等等。)

你可以改写,以便使用登记册,是不是假设的变化,例如 %ebp.只要确定你把它们拖到堆叠在一开始,和流行他们在你的程序。

# count.s: print the numbers from 0 to 100. 
    .text
string: .asciz "%d\n"
    .globl _main

_main:
    push    %ecx
    push    %ebp
    movl    $0, %ecx # The starting point/current value.
    movl    $100,       %ebp # The ending point.

_loop:
    # Display the current value.
    pushl   %ecx
    pushl   $string
    call     _printf
    addl     $8, %esp

    # Check against the ending value.
    cmpl    %ecx, %ebp
    je    _end

    # Increment the current value.
    incl    %ecx
    jmp _loop   

_end:
    pop     %ebp
    pop     %ecx
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top