从堆栈弹出和打印argc

时间:2013-04-16 12:22:19

标签: linux assembly x86 nasm argc

根据this论文和一些stackoverflow帖子, argc 位于堆栈顶部, argv 位于其下方。 我尝试了3-4种不同的方法:

  • 将其弹出到初始化变量(.data)中 - 通过调用printf完成输出。
  • 将其弹出到未初始化的空间(.bss) - 通过调用sys_write()
  • 完成输出
  • 上述+调整的混合物。

我被告知 argc argv 不在论坛的某个人的堆栈中,我不明白;其他人用类似的代码怎么做?

以下是我尝试过的一个例子(3天的知识 - 尽量不要傻笑):

section .bss
        argc:   resd 1      ; alloc 4 bytes for popped value

section .text
        global _start


_start:
        pop   dword[argc]   ; pop argc, place in var
        mov   ebx,0x01      ; file descriptor = STDOUT
        mov   ecx,argc      ; var (addr) - points to buffer
        mov   edx,1         ; length of buffer (single digit)
        mov   eax,0x04      ; syscall number for sys_write()
        int   0x80          ; request the kernel to make syscall

exit:
        mov   ebx,0x00      ; arg for sys_exit() - sys_exit(0)
        mov   eax,0x01      ; syscall number for sys_exit()
        int   0x80          ; request the kernel to make syscall

解决方案:     部分.data             msg db Value: %d\n

section .text
        global main
        extern printf

main:
        push   dword[esp+4]
        push   msg
        call   printf
        add    esp,8

        mov    eax,0
        ret

1 个答案:

答案 0 :(得分:0)

获取argc的过程看起来对我来说没问题(对于32位Linux机器),虽然你的4个字节是关闭的,因为堆栈的顶部很可能包含启动代码的返回地址叫main 此外,sys_write系统调用需要指向ecx中字符串的指针。你给它的是一个指向整数的指针,这不是一回事。
如果你想打印argc的值,你必须先将它转换成一个字符串(或使用printf功能。

这是一些示例代码(我使用的是GNU汇编程序,因为我在这台机器上没有NASM):

format: .asciz "%d\n"
.text
.globl main
  .type main, @function
main:
  pushl 4(%esp)       # push argc
  pushl $format       # push the format string
  call printf
  addl $8,%esp        # pop the arguments

  movl  $0, %eax      # return value 
  ret