0

我在 linux 上使用 NASM 编写一个基本的汇编程序,该程序从 C 库 (printf) 中调用一个函数。不幸的是,这样做时我遇到了分段错误。注释掉对 printf 的调用允许程序运行而不会出错。

; Build using these commands:
;   nasm -f elf64 -g -F stabs <filename>.asm 
;   gcc <filename>.o -o <filename>
;

SECTION .bss    ; Section containing uninitialized data

SECTION .data   ; Section containing initialized data

  text db "hello world",10 ; 

SECTION .text   ; Section containing code


global main

extern printf

;-------------
;MAIN PROGRAM BEGINS HERE
;-------------

main:



      push rbp

      mov rbp,rsp

      push rbx

      push rsi

      push rdi ;preserve registers

      ****************


      ;code i wish to execute

      push text ;pushing address of text on to the stack
      ;x86-64 uses registers for first 6 args, thus should have been:
      ;mov rdi,text (place address of text in rdi)
      ;mov rax,0 (place a terminating byte at end of rdi)

      call printf ;calling printf from c-libraries

      add rsp,8 ;reseting the stack to pre "push text"

      **************  

      pop rdi ;preserve registers

      pop rsi

      pop rbx

      mov rsp,rbp

      pop rbp

      ret
4

2 回答 2

3

x86_64 不将堆栈用于前 6 个参数。您需要将它们加载到正确的寄存器中。那些是:

rdi, rsi, rdx, rcx, r8, r9

我用来记住前两个的技巧是想象函数被memcpy实现为rep movsb

于 2013-03-22T16:57:22.830 回答
0

你正在调用一个可变参数函数—— printf 需要可变数量的参数,你必须在参数堆栈中考虑到这一点。见这里:http ://www.csee.umbc.edu/portal/help/nasm/sample.shtml#printf1

于 2013-03-22T16:48:21.433 回答