1


根据这篇论文和一些stackoverflow帖子,argc在堆栈的顶部,而argv在它的下面。我已经尝试了大约 3-4 种不同的方法:

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

论坛上有人告诉我argcargv不在堆栈中,我不明白;其他人如何使用类似的代码来做这件事?

这是我尝试过的一个例子(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

解决方案:section .data msg dbValue: %d\n

section .text
        global main
        extern printf

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

        mov    eax,0
        ret
4

1 回答 1

0

get 的过程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
于 2013-04-16T12:39:29.307 回答