如何初始化变量,编译和运行GNU汇编程序

时间:2014-11-24 05:56:59

标签: assembly x86 gnu

如何在GNU x86中初始化变量?你如何编译和运行它们?我到处搜索,但找不到合适的教程。这是我的代码。我也不确定我的语法是否正确,因为我仍然无法测试它们

section .data 
    number db 'Enter ten numbers: ', 10
    numberLen equ $-number
    i dw 0 

section .bss
    digits resw 10

section .text
    global _start

_start:
    movw $0, %esi

    movl $4, %eax 
     movl $1, %ebx 
     movl $number, %ecx 
     movl $32, %edx
    int $0x80

    for:
        cmpsw $10, (%i)
        jge skip
        movl $3, %eax 
            movl $0, %ebx
        lea digits(%esi), %ecx
        movl $2, %edx
        int $0x80
        subw $0x30, digits(%esi)
        incw %esi
        incw %i
        jmp for
    skip:
        pushw %digits
        pushw %i
        call sort
        movb $0, %esi
            movw $0, %i
            print:
                cmpsw $10, (%i)
                jge exit
                addw $0x30, digits(%esi)
                movl $4, %eax 
                movl $1, %ebx 
                lea digits(%esi), %ecx
                movl $1, %edx
                int $0x80
                incw %esi
                incw %i
                jmp print
    exit:
        movl $1, %eax 
        movl $0, %ebx
        int $0x80

    sort:
        movw %esp, %ebp
        movb $0, %esi
        for2:
            movw $0, %edi
            cmpsw $10, (%esi)
            jge after
            for3:
                movw digits(%edi), %al
                cmpsw (%edi), (%esi)

                jl cmp2
                cmp1:
                    cmpsw (%al), digits(%esi)
                    jmp continue

                cmp2:
                    cmpsw digits(%esi), (%al)
                continue:
                    jge next
                    movw digits(%esi), %bl

                    movw digits(%edi), %al
                    movw %al, digits(%esi)
                    movw %bl, digits(%edi)
                next:

                    cmpsw $10, (%esi)
                    jge next2
                    incw %edi
                    jmp for3
            next2:
                incw %esi
                jmp for2
        after:  
                ret 6

1 个答案:

答案 0 :(得分:1)

初始化变量

您可以在.data部分初始化变量。你通常这样做:

label: .directive values...

例如,listofnumbers: .byte 1, 2, 3, 4, 5, 6

有一个list of "pseudo-ops",其中包含.ascii.byte等数据定义指令。

您使用listofnumbers在代码中引用$listofnumbers的地址,使用listofnumbers引用地址中的值。因此movl $listofnumbers, %eax会将listofnumbers的地址放在eax寄存器中,movb listofnumbers, %al会将字面值1放在{{1}的低位字节中注册。

编译代码

要将eax编译为可执行文件filename.S,我建议:

filename

gcc -nostdlib -g -o filename filename.S阻止gcc尝试链接寻找-nostdlib函数的标准库例程。

main使用调试符号编译代码。这意味着您可以使用gdb(-g)运行代码,设置断点,并在gdb内部逐步执行代码(例如gdb filenamebreak 1run。在gdb中,stepinfo reg将让您查看寄存器和堆栈周围的内存区域。

您可以使用简单的x/100xw $ebp-50来运行您的代码,但我建议使用./filename因为它会让很多更容易看到当您意外发生时会发生什么结果