x86 32位装配 - 打印效果行为的位置

时间:2014-05-07 23:47:45

标签: assembly compiler-construction

我目前正在为Java的一个子集编写一个编译器,并且可以将代码转换为x86 32位汇编。我已经能够编写一些程序了,但是下面的程序给我带来了麻烦:

class DummySort {
    public static void main(String[] a){
        DS ds = new DS();
        ds.Start(12);
    }
}


// This class contains the array of integers and
// methods to initialize, print and sort the array
class DS{

    int[] number ;
    int size ;

    // Invoke the Initialization, Sort and Printing
    // Methods
    public void Start(int sz){
        int aux01 ;
        aux01 = this.Init(sz);
        System.out.printf("%s\n","----- UNSORTED -----");
        this.Print("U");
    }

    // Print array of integers
    public void Print(String s){
        int j = 0;
        int n = 0;
        while (j < (size)) {
            //Switching prints change behavior
            System.out.printf("%d at %d with %s\n",number[j],j,s);
            n = j;
            j = j + 1 ;
            //System.out.printf("%d at %d with %s\n",number[n],n,s);
        }
    }

    // Initialize array of integers
    public int Init(int sz){
        size = sz ;
        number = new int[sz] ;

        number[0] = 20 ;
        number[1] = 7  ; 
        number[2] = 12 ;
        number[3] = 18 ;
        number[4] = 2  ; 
        number[5] = 11 ;
        number[6] = 6  ; 
        number[7] = 9  ; 
        number[8] = 19 ; 
        number[9] = 5  ;
        number[10] = 25;
        number[11] = 0;
        return 0 ;  
    }

}

主要问题来自于切换使用哪个print语句。第一个结果是无限循环打印:

7 at 1 with U

使用第二个打印而不是第一个打印产生以下内容并终止:

----- UNSORTED -----
2 at 4 with U
2 at 4 with U
2 at 4 with U
2 at 4 with U
2 at 4 with U
2 at 4 with U
2 at 4 with U
2 at 4 with U
2 at 4 with U
2 at 4 with U
2 at 4 with U
2 at 4 with U

这是我的程序在上述情况下生成的程序集:

    .file   "DummySort.s"
    .section     .rodata
STR0:
    .ascii "%d at %d with %s\12\0"
STR1:
    .ascii "%s\12\0"
STR2:
    .ascii "----- UNSORTED -----\0"
STR3:
    .ascii "U\0"
    .text
    #CODEBLOCK: prog: 0
    #CODEBLOCK: DS
    #CODEBLOCK: DS:new
DS_new:
    pushl  %ebp
    movl  %esp, %ebp
    #CODEBLOCK: save
    pushl  %edx
    pushl  %ebx
    pushl  %ecx
    pushl  %esi
    #END_BLOCK: save

    pushl  $8
    call  _malloc
    addl  $4, %esp
    #CODEBLOCK: restore
    popl  %esi
    popl  %ecx
    popl  %ebx
    popl  %edx
    #END_BLOCK: restore

    movl  %eax, %esi
    #CODEBLOCK: varDec: 14
    movl  $0, (%esi)
    #END_BLOCK: varDec: 14

    #CODEBLOCK: varDec: 18
    movl  $0, 4(%esi)
    #END_BLOCK: varDec: 18

    movl  %esi, %eax
    movl  %ebp, %esp
    popl  %ebp
    ret
    #END_BLOCK: DS:new

    #CODEBLOCK: DS:Methods: 0
    #CODEBLOCK: DS:Start
DS_Start:
    pushl  %ebp
    movl  %esp, %ebp
    #CODEBLOCK: varDec: 20
    movl  $0, -4(%ebp)
    #END_BLOCK: varDec: 20

    #CODEBLOCK: assignStat: 21
    #CODEBLOCK: save
    pushl  %edx
    pushl  %ebx
    pushl  %ecx
    pushl  %esi
    #END_BLOCK: save

    #CODEBLOCK: call
    pushl  8(%ebp)
    call  DS_Init
    addl  $4, %esp
    #END_BLOCK: call

    #CODEBLOCK: restore
    popl  %esi
    popl  %ecx
    popl  %ebx
    popl  %edx
    #END_BLOCK: restore

    movl  %eax, %edx
    movl  %edx, -4(%ebp)
    #END_BLOCK: assignStat: 21

    #CODEBLOCK: funcStat: 22
    #CODEBLOCK: save
    pushl  %edx
    pushl  %ebx
    pushl  %ecx
    pushl  %esi
    #END_BLOCK: save

    #CODEBLOCK: call
    pushl  $STR2
    pushl  $STR1
    call  _printf
    addl  $8, %esp
    #END_BLOCK: call

    #CODEBLOCK: restore
    popl  %esi
    popl  %ecx
    popl  %ebx
    popl  %edx
    #END_BLOCK: restore

    #END_BLOCK: funcStat: 22

    #CODEBLOCK: funcStat: 23
    #CODEBLOCK: save
    pushl  %edx
    pushl  %ebx
    pushl  %ecx
    pushl  %esi
    #END_BLOCK: save

    #CODEBLOCK: call
    pushl  $STR3
    call  DS_Print
    addl  $4, %esp
    #END_BLOCK: call

    #CODEBLOCK: restore
    popl  %esi
    popl  %ecx
    popl  %ebx
    popl  %edx
    #END_BLOCK: restore

    #END_BLOCK: funcStat: 23

    movl  %ebp, %esp
    popl  %ebp
    ret
    #END_BLOCK: DS:Start

    #CODEBLOCK: DS:Print
DS_Print:
    pushl  %ebp
    movl  %esp, %ebp
    #CODEBLOCK: varDec: 28
    movl  $0, -4(%ebp)
    #END_BLOCK: varDec: 28

    #CODEBLOCK: varDec: 29
    movl  $0, -8(%ebp)
    #END_BLOCK: varDec: 29

    #CODEBLOCK: whileStat: 36
WHILE1:
    movl  -4(%ebp), %edx
    xor   %eax, %eax
    cmp   4(%esi), %edx
    setl  %al
    movl  %eax, %edx
    cmp  $0, %edx
    je    ENDWHILE1
    #CODEBLOCK: blockStat: 36
    #CODEBLOCK: funcStat: 32
    #CODEBLOCK: save
    pushl  %edx
    pushl  %ebx
    pushl  %ecx
    pushl  %esi
    #END_BLOCK: save

    #CODEBLOCK: call
    pushl  8(%ebp)
    pushl  -4(%ebp)
    movl  -4(%ebp), %edx
    movl  (%esi), %ebx
    pushl  (%ebx,%edx,4)
    pushl  $STR0
    call  _printf
    addl  $16, %esp
    #END_BLOCK: call

    #CODEBLOCK: restore
    popl  %esi
    popl  %ecx
    popl  %ebx
    popl  %edx
    #END_BLOCK: restore

    #END_BLOCK: funcStat: 32

    #CODEBLOCK: assignStat: 33
    movl  -4(%ebp), %eax
    movl  %eax, -8(%ebp)
    #END_BLOCK: assignStat: 33

    #CODEBLOCK: assignStat: 35
    movl  -4(%ebp), %edx
    addl  $1, %edx
    movl  %edx, -4(%ebp)
    #END_BLOCK: assignStat: 35

    #END_BLOCK: blockStat: 36

    jmp   WHILE1
ENDWHILE1:
    #END_BLOCK: whileStat: 36

    movl  %ebp, %esp
    popl  %ebp
    ret
    #END_BLOCK: DS:Print

    #CODEBLOCK: DS:Init
DS_Init:
    pushl  %ebp
    movl  %esp, %ebp
    #CODEBLOCK: assignStat: 41
    movl  8(%ebp), %eax
    movl  %eax, 4(%esi)
    #END_BLOCK: assignStat: 41

    #CODEBLOCK: assignStat: 43
    movl  8(%ebp), %edx
    imul  $4, %edx
    #CODEBLOCK: save
    pushl  %edx
    pushl  %ebx
    pushl  %ecx
    pushl  %esi
    #END_BLOCK: save

    pushl  %edx
    call  _malloc
    addl  $4, %esp
    #CODEBLOCK: restore
    popl  %esi
    popl  %ecx
    popl  %ebx
    popl  %edx
    #END_BLOCK: restore

    movl  %eax, %edx
    movl  %edx, (%esi)
    #END_BLOCK: assignStat: 43

    #CODEBLOCK: arrAssignStat: 44
    movl  $20, %edx
    movl  $0, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 44

    #CODEBLOCK: arrAssignStat: 45
    movl  $7, %edx
    movl  $1, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 45

    #CODEBLOCK: arrAssignStat: 46
    movl  $12, %edx
    movl  $2, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 46

    #CODEBLOCK: arrAssignStat: 47
    movl  $18, %edx
    movl  $3, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 47

    #CODEBLOCK: arrAssignStat: 48
    movl  $2, %edx
    movl  $4, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 48

    #CODEBLOCK: arrAssignStat: 49
    movl  $11, %edx
    movl  $5, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 49

    #CODEBLOCK: arrAssignStat: 50
    movl  $6, %edx
    movl  $6, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 50

    #CODEBLOCK: arrAssignStat: 51
    movl  $9, %edx
    movl  $7, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 51

    #CODEBLOCK: arrAssignStat: 52
    movl  $19, %edx
    movl  $8, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 52

    #CODEBLOCK: arrAssignStat: 53
    movl  $5, %edx
    movl  $9, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 53

    #CODEBLOCK: arrAssignStat: 54
    movl  $25, %edx
    movl  $10, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 54

    #CODEBLOCK: arrAssignStat: 55
    movl  $0, %edx
    movl  $11, %ebx
    movl  (%esi), %ecx
    movl  %edx, (%ecx,%ebx,4)
    #END_BLOCK: arrAssignStat: 55

    #CODEBLOCK: returnStat: 56
    movl  $0, %eax
    movl  %ebp, %esp
    popl  %ebp
    ret
    #END_BLOCK: returnStat: 56

    #END_BLOCK: DS:Init

    #END_BLOCK: DS:Methods: 0

    #END_BLOCK: DS

    #CODEBLOCK: _main
.globl _main
_main:
    #CODEBLOCK: mainPre
    pushl  %ebp
    movl  %esp, %ebp
    #END_BLOCK: mainPre

    #CODEBLOCK: mMtdLocs
    subl  $4, %esp
    #END_BLOCK: mMtdLocs

    #CODEBLOCK: varDec: 4
    #CODEBLOCK: save
    pushl  %edx
    pushl  %ebx
    pushl  %ecx
    pushl  %esi
    #END_BLOCK: save

    call  DS_new
    #CODEBLOCK: restore
    popl  %esi
    popl  %ecx
    popl  %ebx
    popl  %edx
    #END_BLOCK: restore

    movl  %eax, %edx
    movl  %edx, -4(%ebp)
    #END_BLOCK: varDec: 4

    #CODEBLOCK: funcStat: 5
    #CODEBLOCK: save
    pushl  %edx
    pushl  %ebx
    pushl  %ecx
    pushl  %esi
    #END_BLOCK: save

    #CODEBLOCK: call
    pushl  $12
    movl  -4(%ebp), %esi
    call  DS_Start
    addl  $4, %esp
    #END_BLOCK: call

    #CODEBLOCK: restore
    popl  %esi
    popl  %ecx
    popl  %ebx
    popl  %edx
    #END_BLOCK: restore

    #END_BLOCK: funcStat: 5

    #CODEBLOCK: mainEnd
    movl  $0, %eax
    movl  %ebp, %esp
    popl  %ebp
    ret
    #END_BLOCK: mainEnd

    #END_BLOCK: _main

    #END_BLOCK: prog: 0

我一直在看这段代码几个小时,非常感谢任何帮助。我可以发布在第二种情况下生成的程序集,但除了代码块的定位外,它似乎完全相同。

如果有人要求提供更多生成的示例,请告诉我并再次感谢!

1 个答案:

答案 0 :(得分:1)

StartPrint中,您不会从堆栈中为本地人分配空间。 IE浏览器。你错过了sub $x, %esp。因此,你的推送和电话将覆盖当地人,造成严重破坏。

$ ./a.out
----- UNSORTED -----
20 at 0 with U
7 at 1 with U
12 at 2 with U
18 at 3 with U
2 at 4 with U
11 at 5 with U
6 at 6 with U
9 at 7 with U
19 at 8 with U
5 at 9 with U
25 at 10 with U
0 at 11 with U

耶! \ O /