0

これは foo.asm です

extern choose;
[section .data]
num1st dq 3
num2nd dq 4
[section .text]
global main
global myprint
main:
  push qword [num2nd]
  push qword [num1st]
  call choose
  add esp,8
  mov ebx,0
  mov eax,1
  int 0x80
  ;  pop qword [num1st]
  ;  pop qword [num2nd]
myprint:
  mov edx,[esp+8]
  mov ecx,[esp+4]
  mov ebx,1
  mov eax,4
  int 0x80
  ;  pop qword [num1st]
  ;  pop qword [num2nd]
  ret

それはC-asm-プログラムです

これはbar.cです

void myprint(char * msg ,int len);
int choose(int a,int b) 
{ 
  if (a>=b){
    myprint("the 1st one\n",13);}
  else {
    myprint("the 2nd one\n",13);}
  return 0;
}

nasm -f elf64 foo.asm

gcc -c bar.c

gcc -s -o foobar bar.o foo.o

./foobar 、セグメンテーション違反のコアダンプが表示されます

gdb を使用してデバッグしていますが、debuginfo-install が見つからないと表示され、インストールしようとしています。

おそらく問題は 86_64 アーチに関係しているのでしょう...

このリンクを見た後にスタック (NASM) をプッシュすると、セグメンテーション違反が発生しました 。「ポップ」を追加しましたが、機能しません。

4

1 に答える 1

1

64 ビット モードでは、6 つ以上の引数がない限り、引数はスタックに渡されません。最初の 2 つの引数は inRDIとになりRSIます。

また、64 ビット モードでのシステム コールの使用方法にも違いがあります。syscall 番号と引数は、次のレジスタ ( source )に配置する必要があります。

syscall nr  rax
arg 1       rdi
arg 2       rsi
arg 3       rdx
arg 4       r10
arg 5       r9
arg 6       r8

また、sys_write64 ビット モードでの syscall 番号は 4 ではなく 1です。また、代わりにint 0x80 を使用する必要がありますsyscall。syscall の実行は、カーネルの構成方法によっては 64 ビット モードで機能する場合がありますが、関数の引数がどのように渡されるかを考慮する必要がありますint 0x80

于 2013-06-25T07:52:03.547 に答える