这个汇编代码中的执行顺序? (NASM)

时间:2016-02-23 05:29:59

标签: assembly x86 nasm

我试着寻找答案,而且任何相似的例子都太简单或太复杂。我使用Paul Carter的书作为集会课,所以有些宏来自他。即,print_string,print_int和print_nl函数。

鉴于这个汇编片段:

segment .data

        output db "Welcome!",0
        string1 db "greater than",0
        string2 db "less than",0
        string3 db "equal to",0
        var_a dd 0Ah

segment .bss

segment .text
        global  _asm_main

_asm_main:

        enter   0,0               ; setup routine
        pusha
    ;***************CODE STARTS HERE***************************

        mov eax, output
        call print_string
        call print_nl

        cmp dword[var_a], 0Ah
        jle label1
        mov eax, string1
        call print_string
        call print_nl
        jmp label3

    label1:
        cmp dword[var_a], 9h
        jg label2
        mov eax, string2
        call print_string
        call print_nl
        jmp label3
    label2:
        mov eax, string3
        call print_string
        call print_nl
    label3:
        cmp dword [var_a], 0
        jle label4
        sar [var_a], 1
        mov eax, dword [var_a]
        call print_int
        call print_nl
        jmp label3
    label4:

    ;***************CODE ENDS HERE*****************************
        popa
        mov     eax, 0            ; return back to C
        leave
        ret

输出为:

欢迎!

equal to
5
2
1
0

我的问题:

我看到它最终如何通过比较获得label2,打印"等于"消息和新行。在那之后,我看到label2中没有额外的比较。那时,label3甚至被调用了?该计划如何离开" LABEL2?我理解程序集中的所有内容,除了在label2的末尾(打印"等于")和label3的开头(它循环移位并打印数字)之间。我错过了什么吗?

执行label2后,程序的控制权是否会回到label1首次调用label2的位置?或者label3是否执行,因为它接下来是顺序的?

1 个答案:

答案 0 :(得分:2)

想象一下,您的代码根本没有标签。机器将在列表中逐个执行指令。添加标签根本不会改变这种行为;除非有跳跃,否则机器仍然会转到下一条指令。

标签给出了内存地址的名称。它们在跳跃时很有用。如果我们没有标签,那么我们可能需要这样做:

add foo, bar
sub foo, bar
mul foo, bar
jmp -2         ; Fake code for "go up 2 instructions"

使用标签,我们可以为指令的内存地址命名:

  add foo, bar
thingamajig:       ; This label equals the address of the 'sub' instruction
  sub foo, bar
  mul foo, bar
  jmp thingamajig
相关问题