2016-11-07 6 views
-5

linuxのアセンブリ言語からprintf関数を呼び出したい。nasmを使用した64ビットおよび32ビットアーキテクチャのアセンブリ言語からprintfを呼び出す

私は、64ビットおよび32ビットアセンブリ言語プログラムの方法を知りたいと思っています。

1)printfに32ビットの引数と64ビットの引数を文字列で渡したい場合は、2つのケースについて教えてください。どうすればいいですか? x86の32ビットアーキテクチャのための

2は、i)は、ポイント1

私のコードを教えてくださいと同じことをしたい場合。私は両方のケースのスタックを調整する必要がありますと私はレジスタでarguementsを渡す必要があることを教えてください?

おかげで

+0

私はcorei7 64ビットアーキテクチャを使用しています。 32ビットと64ビットの両方のプログラムでprintfを呼び出す方法を知りたい。私は、引数のどこを渡すか、呼び出し後に手動でスタックを調整する必要があるかどうかを知りたい。どちらの場合も私に例を挙げてください。両方の場合に文字列を含む32ビットと64ビットの引数を渡すためのものです。 – user2277648

+0

_ "printf nasm" _または_ "x86-64 printf nasm" _を検索するときの最初のヒットは、printfを呼び出すプログラムをはじめとする一連のプログラムの例です。 – Michael

答えて

1

たくさんのLinuxでのアセンブリ言語の文字列を印刷する2通りの方法があります。

1)x64の場合はsyscall、x86の場合はint 0x80を使用します。それはprintfではなく、カーネルルーチンです。あなたはさらにhere (x86)here (x64)を見つけることができます。

2)glibcのprintfを使用してください。私はacm.mipt.ruから素敵なx86の例であるので、ここで、あなたはNASMプログラムの構造に精通していると仮定します。

global main 

;Declare used libc functions 
extern exit 
extern puts 
extern scanf 
extern printf 

section .text 

main: 

;Arguments are passed in reversed order via stack (for x86) 
;For x64 first six arguments are passed in straight order 
; via RDI, RSI, RDX, RCX, R8, R9 and other are passed via stack 
;The result comes back in EAX/RAX 
push dword msg 
call puts 
;After passing arguments via stack, you have to clear it to 
; prevent segfault with add esp, 4 * (number of arguments) 
add esp, 4 

push dword a 
push dword b 
push dword msg1 
call scanf 
add esp, 12 
;For x64 this scanf call will look like: 
; mov rdi, msg1 
; mov rsi, b 
; mov rdx, a 
; call scanf 

mov eax, dword [a] 
add eax, dword [b] 
push eax 
push dword msg2 
call printf 
add esp, 8 

push dword 0 
call exit 
add esp, 4 
ret 

section .data 
msg : db "An example of interfacing with GLIBC.",0xA,0 
msg1 : db "%d%d",0 
msg2 : db "%d", 0xA, 0 

section .bss 
a resd 1 
b resd 1 

あなたは組立それx86用gcc -m32 -o foo foo.onasm -f elf32 -o foo.o foo.asmとリンクとすることができます。 x64の場合は、elf32elf64と置き換え、-m32-m64に置き換えてください。 gccを使用してx64システムにx86プログラムを構築するには、gcc-multilibが必要です。

+1

実際には '_start'(' main'の代わりに)を定義する '.o'をリンクするには' gcc -nostartfiles'が必要です。完全な詳細については、http://stackoverflow.com/questions/36861903/assembling-32-bit-binaries-on-a-64-bit-system-gnu-toolchain/36901649#36901649を参照してください。 –

+1

また、CALLの後にサブを追加する必要はありません。 'sub esp、12'はもっと多くのスタックスペースを予約します。または、ESPだけを残して、MOV命令でポップしなかったスペースに格納して、次のCALLをセットアップします。 –

+0

@PeterCordesああ、ありがとう、私は少しそれを台無しにしました – trexxet

関連する問題