2016-11-07 11 views
-5

Я хочу вызвать функцию printf из языка ассемблера в linux.вызов printf из языка ассемблера на 64-битной и 32-битной архитектуре с использованием nasm

Я хочу знать метод для 64-битных и 32-битных ассемблерных программ.

1) скажите мне два случая, если я хочу передать 32-битный аргумент и 64-битное утверждение в printf со строкой. Как я должен это делать?

2) для x86 32-битной архитектуры, если я хочу сделать то же самое, что и в пункте 1.

пожалуйста скажите мне код. и дайте мне знать, нужно ли мне настраивать стек для обоих случаев, и мне просто нужно передать аргументы в регистрах?

Большое спасибо

+0

Я использую 64-разрядную архитектуру Corei7. но я хочу знать метод вызова printf в 32-битных и 64-битных программах. Я хочу знать, где передать аргументы и нужно ли отрегулировать стек вручную после вызова. просьба привести пример для обоих случаев. для передачи 32-битных и 64-битных аргументов со строкой в ​​обоих случаях. – user2277648

+0

Самый первый хит, когда googling _ "printf nasm" _ или _ "x86-64 printf nasm" _ - это страница с кучей примеров программ, включая ту, которая вызывает 'printf'. – Michael

ответ

1

Есть 2 способа, чтобы напечатать строку с ассемблере в Linux.

1) Используйте syscall для x64, или int 0x80 для x86. Это не printf, это подпрограммы ядра. Вы можете найти более here (x86) и here (x64).

2) Используйте printf от glibc. Я предполагаю, что вы знакомы со структурой программы NASM, так вот хороший пример x86 от acm.mipt.ru:

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 и связь с gcc -m32 -o foo foo.o для x86. Для x64 просто замените elf32 на elf64 и -m32 с -m64. Обратите внимание, что вам нужно gcc-multilib для создания x86-программ на x64-системе с использованием gcc.

+1

Вам действительно нужно 'gcc -nostartfiles' связать' .o', который определяет '_start' (вместо' main'). Для получения полной информации см. 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 oh спасибо, я немного испортил его – trexxet

 Смежные вопросы

  • Нет связанных вопросов^_^