2014-11-24 33 views
-1

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

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 
+0

_“你如何初始化GNU x86中的变量?以及如何编译和运行它们?”_你不编译或运行变量。将汇编代码组装到目标代码中,然后将其链接到可运行的可执行文件中。你能指出你不确定的具体行吗? – Michael 2014-11-24 08:13:20

+0

如果你可以评论你的代码(每条评论通常被认为是最好的),我们将有一个更容易理解和帮助你的时间。目前,我无法确定你的代码试图做什么。 – 2014-11-24 08:55:15

回答

1

正在初始化变量

您可以初始化变量。你通常会做这样的:

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放入eax寄存器的低字节中。

编译代码

编译filename.S成可执行filename,我建议:

gcc -nostdlib -g -o filename filename.S

-nostdlib停止GCC试图链接标准库例程将寻找一个main功能。

-g用调试符号编译代码。这意味着您可以使用gdb(gdb filename)运行代码,设置断点并遍历代码(例如,在gdb中运行一次即可使用break 1,run,step)。在gdb中,info regx/100xw $ebp-50可让您查看堆栈周围的寄存器和内存区域。

你可以用一个简单的./filename运行你的代码,但我建议gdb,因为它将使一个很多更容易看到什么,当你得到意想不到的效果上会。

+0

我在这部分subw $ 0x30数字(%esi)出现分段错误。它出什么问题了? – 2014-12-01 07:49:31

+0

上面的代码甚至没有为我编译(它看起来像是NASM和GAS语法的混合,所以我并不感到惊讶)。这使得很难说出你的错误是什么。分段错误通常表示您尝试对您应该没有触及的内存执行操作。 – Tony 2014-12-01 10:10:39