关于操纵全局数组的汇编代码的分段错误

时间:2016-11-27 15:30:53

标签: arrays pointers assembly

我正在开发一个关于获取输入字符串的项目 0011001101100110(8位,16位,32位....) 将每个8位值存储到一个数组字节

但是,我刚遇到代码的分段错误。 void函数和无函数参数是否需要推步?

    laser.asm

    section .data
    message: times 128 db 0 

    section .text
    USE32

    global _start
    _start:
          push ebp
          mov esp, ebp
          call decode_message
          call print_message

          mov ebx, 0
          mov eax, 1
          int 80h

     print_character:

          push ebp
          mov ebp, esp
          push ebx

          mov eax, 4
          mov ebx, 1
          lea ecx, [ebp+8]
          mov edx, 1
          int 0x80

          pop ebx
          leave
          ret

     read_character:

          push ebp
          mov ebp, esp
          sub esp, 4
          push ebx

          mov eax, 3
          mov ebx, 0
          lea ecx, [ebp-4]
          mov edx, 1
          int 0x80

          mov eax, [ebp-4]
          pop ebx
          add esp, 4
          leave
          ret

     get_bit:
          push ebp
          mov ebp, esp
          call read_character
          cmp eax, 48
          je zero

          cmp eax, 49
          je one

          zero:
          mov eax, 0
          leave
          ret
          one:
          mov eax, 1
          leave
          ret

     get_byte:
         push ebp
         mov ebp, esp
         mov ebx, 8
         cmp ebx, 0
         mov ecx, eax
         jge end

         call get_bit
         cmp eax, 0
         je b_zero

         cmp eax, 1
         je b_one

         b_zero:
         shl ecx, 1 
         jmp end

         b_one:
         shl ecx, 1
         or ecx, 1
         jmp end    

         end:
         mov eax, ecx
         leave
         ret

     decode_message:
         push ebp
         mov ebp, esp
         sub esp, 0x128
         mov DWORD [ebp-0x4], 0x0;
         call get_byte
         jmp d_test

         d_loop:
         mov ebx, DWORD [ebp-0x4];
         mov edx, eax
         mov DWORD [ebx*4+0x804a040], edx;
         add DWORD [ebp-0x4], 0x1;  
         call get_byte

         d_test:
         cmp eax, 0
         jne d_loop
         leave
         ret

     print_message:
         push ebp
         mov ebp, esp
         sub esp, 0x128
         mov DWORD [ebp-0x4], 0x0;
         jmp p_test

         p_loop:
         mov ebx, DWORD [ebp-0x4];
         mov eax, DWORD [ebx*4+0x804a040];
         push eax
         call print_character
         add esp, 4
         add DWORD [ebp-0x4], 0x1;

         p_test:
         cmp eax, 0
         jne p_loop
         leave
         ret

1 个答案:

答案 0 :(得分:1)

_start:
    push ebp
    mov esp, ebp
    call decode_message

mov esp, ebp指令必须为mov ebp, esp

get_byte:
    push ebp
    mov ebp, esp
    mov ebx, 8
    cmp ebx, 0
    mov ecx, eax
    jge end

此过程将始终跳转到 end 标签!您在EBX寄存器中移动了值8,然后将其与0进行比较。这始终设置更大条件。因此,您的代码永远不会call get_bitcall read_character 这样EAX寄存器不会超时更改,并且由于父程序 decode_message 仅在EAX非零时循环,因此您的程序可以默默地执行任何操作所有(如果你很幸运)。但是就目前而言,你还有另外两个问题会最终触发分段错误:

  • 在调用 decode_message 过程之前,您没有设置EAX。它很可能非零。
  • 您使用了一些非常可疑的内存偏移量(0x804a040)。