【问题标题】:Assembly Language - Sub program汇编语言 - 子程序
【发布时间】:2016-09-27 05:37:47
【问题描述】:

我有一个问题:如果通用寄存器(GPR)在堆栈之间共享(我认为是),那么传递堆栈空间地址的唯一方法是否是使用 GPR?

任何建议将不胜感激。提前致谢。

      segment .data
      prompt db "Enter an integer number (0 to quit): ",0

      segment .text
main:
            enter 0,0
            pusha
            mov eax, prompt
            call print_string
            call print_nl
            call read_int
            mov dword [ebp+8], eax
            dump_stack 1,2,4
            call calc_sum
            mov eax, [ebp+12]
            call print_int
            call print_nl

            popa
            mov eax, 0      ; return value
            leave           ; deallocate stack frame
            ret
           ; sump            [ebp+12]                > int ptr
           ; n               [ebp+8]                 > current number
           ; return address  [ebp+4]                 
           ; ebp             [ebp]                   
           ; sum             [ebp-4]                 
           ; i               [ebp-8]                 
            global calc_sum
    calc_sum:
            enter 4,0               ; stack space allocated for sum
            push ebx                ; very important!

            mov dword [ebp-4], 0    ; sum = 0
            dump_stack 1,2,4        ; print the content of stack from ebp-8 to ebp+16 
            mov ecx, 1              ; ecx psuedo code i
    for_loop:
            cmp ecx, [ebp+8]        ;cmp i and n
            jnle end_for            ; if i<= n else ,  exit 

            add [ebp-4], ecx        ; sum+=i
            inc ecx
            jmp short for_loop
    end_for:
            mov ebx, [ebp+12]       ;ebx = sump
            mov eax, [ebp-4]        ;eax = sum
            mov [ebx], eax

            pop ebx                 ;restore ebx
            leave


  Enter an integer number (0 to quit): 
 10
 Stack Dump # 1
 EBP = BF86F3D8 ESP = BF86F3B8
  +16  BF86F3E8  BF86F47C
  +12  BF86F3E4  BF86F474
   +8  BF86F3E0  0000000A
   +4  BF86F3DC  B76134E3
   +0  BF86F3D8  00000000
   -4  BF86F3D4  00000001
   -8  BF86F3D0  BF86F474
 Stack Dump # 1
 EBP = BF86F3B0 ESP = BF86F3A8
  +16  BF86F3C0  BF86F3D8
  +12  BF86F3BC  00000000
   +8  BF86F3B8  00000000
   +4  BF86F3B4  080484AC
   +0  BF86F3B0  BF86F3D8
   -4  BF86F3AC  00000000
   -8  BF86F3A8  B77A0FF4
 Segmentation fault (core dumped)

dump_stack 1,2,4 (-8~+16)

显示堆栈帧。我附上了执行程序的结果。我得到了这个结果,以防你不明白dump_stack

顺便说一句:我使用NASMgcc 作为学习工具。

【问题讨论】:

    标签: assembly x86 stack nasm


    【解决方案1】:

    首先,只有一个堆栈,所以堆栈之间不能共享任何东西,因为只有一个(实际上是一种简化,但只要你是初学者就可以这样考虑)。

    将堆栈想像为您的数据的一些空间。每个push callret 都只是读/写到这个地方。像eax 这样的寄存器不受影响(直到你调用pop eax :))。

    所以每次使用pushcall 写入堆栈都会减少esp 寄存器(这就是我们说它增长的原因),而每次使用popret 读取都会增加它。 esp 总是指向栈顶。您可以通过movesp 读取或修改到/从另一个寄存器读取或修改esp,但您必须知道自己在做什么。

    【讨论】:

      猜你喜欢
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-07
      • 2014-12-26
      • 1970-01-01
      相关资源
      最近更新 更多