使用nasm在64位和32位架构上使用汇编语言调用printf

时间:2016-11-07 06:13:37

标签: linux assembly printf 64-bit nasm

我想在linux中用汇编语言调用printf函数。

我想知道64位和32位汇编语言程序的方法。

1)如果我想在printf中用字符串传递32位争论和64位争论,请告诉我两种情况。我应该怎么做?

2)对于x86 32位架构,如果我想做与第1点相同的事情。

请告诉我代码。让我知道我是否需要调整两种情况的堆栈,我只需要在寄存器中传递争论吗?

非常感谢

1 个答案:

答案 0 :(得分:2)

在Linux中有两种使用汇编语言打印字符串的方法。

1)对{x64}使用syscall,对x86使用int 0x80。它不是printf,它的内核例程。您可以找到更多here (x86)here (x64)

2)使用glibc中的printf。我假设您熟悉NASM程序的结构,所以这里有一个来自acm.mipt.ru的x86示例:

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

您可以使用nasm -f elf32 -o foo.o foo.asm对其进行汇总,并为x86与gcc -m32 -o foo foo.o相关联。对于x64,只需将elf32替换为elf64,将-m32替换为-m64。请注意,您需要gcc-multilib使用gcc在x64系统上构建x86程序。