2015-02-19 2 views
1

У меня есть 2 программы: один из них выполняет вход-вывод (C++), а другой вычисляет формулу (сборку). Они работают друг с другом.Ввод-вывод сборки

Эта программа делает вход-выход:

#include <iostream> 

using namespace std; 

extern "C" int calc(int a, int b, int c, int d); 

int main() 
{ 
    int a; 
    cout<<"a:"<<endl; 
    cin>>a; 
    cout<<"b:"<<endl; 
    int b; 
    cin>>b; 
    cout<<"c:"<<endl; 
    int c; 
    cin>>c; 

    cout<<"d:"<<endl; 
    int d; 
    cin>>d; 

    int calculation = calc(a,b,c,d); 
    cout << "5*a-c*d+7*b-2=" <<calculation<< endl; 
    return 0; 
} 

И эта программа вычисляет результат:

format ELF 

public calc 

calc: 
    push ebp 
    mov ebp, esp 
label a dword at ebp+8 
label b dword at ebp+12 
label c dword at ebp+16 
label d dword at ebp+20 

mov eax, [a] 
mov ebx, 5 
mul ebx 
mov ecx, eax 

mov eax, [c] 
mov ebx, [d] 
mul ebx 
sub ecx, eax 


mov eax, [b] 
mov ebx, 7 
mul ebx 
add eax, ecx 

sub eax, 2 
mov esp, ebp 
pop ebp  
ret   

Можете ли вы помочь мне делать ввод-вывод также в Ассамблее (без C++ программы)? Я не уверен, как это сделать в этом примере. Оцените любую помощь.

+0

Какой ассемблер (FASM?) Вы хотите использовать? Как вы собрали, скомпилировали и связали две программы? – rkhb

+0

@rkhb Я использую fasm, чтобы скомпилировать обе программы, я использую 'g ++ -m32 calc.cpp calcul.o -o a.out' – uliana291

ответ

0

Вы можете использовать функции из библиотеки C (libc) из кода сборки. Подробная информация о том, как использовать функции C, зависит от того, какой ассемблер используется. Также, какие регистры и/или стек используются для параметров функции и в каком порядке зависят от исполняемой цели (32-разрядной или 64-разрядной). Например Yasm ассемблере синтаксис для вызова функции Scanf на 64-битных Linux может быть:

segment .data 
format: db "%d" ;format string used in scanf("%d", &var) 
var: dd 123 ;variable where we want to read input to (initialized to a random number 123) 
segment .text 
global main 
extern scanf 
main: 
lea rax, [var] 
lea edi, [format] 
xor eax, eax 
call scanf 

Для получения исполняемого файла:

  • yasm -f elf64 usingClib.s
  • gcc usingClib.o -o usingClib

I предложите использовать gcc вместо ld, так как gcc по умолчанию связывает библиотеку C.

0

Практически невозможно запрограммировать cin и cout вручную в сборе. Но вы можете использовать функции printf и scanf из C-библиотеки, которая является подмножеством C++ - стандарт:

format ELF 
public main 
extrn printf 
extrn scanf 
extrn fflush 

section '.text' executable 

calc: 
label .a dword at ebp+8     ; Labels with dot are local labels 
label .b dword at ebp+12 
label .c dword at ebp+16 
label .d dword at ebp+20 

    push ebp 
    mov ebp, esp 

    mov eax, [.a] 
    mov ebx, 5 
    mul ebx 
    mov ecx, eax 
    mov eax, [.c] 
    mov ebx, [.d] 
    mul ebx 
    sub ecx, eax 
    mov eax, [.b] 
    mov ebx, 7 
    mul ebx 
    add eax, ecx 
    sub eax, 2 

    mov esp, ebp 
    pop ebp 
    ret 

main: 
label .calculation dword at ebp-4  ; Labels with dot are local labels 
label .a dword at ebp-8 
label .b dword at ebp-12 
label .c dword at ebp-16 
label .d dword at ebp-20 

    push ebp 
    mov ebp, esp 
    sub esp, 20       ; Space for the local variables 

    lea eax, [in_msg] 
    push eax 
    call printf       ; printf ("a: "); 
    add esp, 4 

    lea eax, [.a]      ; Pointer to .a (effective address of .a) 
    push eax 
    push scan_fmt 
    call scanf       ; scanf (" %d", &a); 
    add esp, 8       ; Clean up the stack 

    lea eax, [in_msg+4] 
    push eax 
    call printf       ; printf ("b: "); 
    add esp, 4 

    lea eax, [.b]      ; Pointer to .a (effective address of .a) 
    push eax 
    push scan_fmt 
    call scanf       ; scanf (" %d", &b); 
    add esp, 8       ; Clean up the stack 

    lea eax, [in_msg+8] 
    push eax 
    call printf       ; printf ("c: "); 
    add esp, 4 

    lea eax, [.c]      ; Pointer to .a (effective address of .a) 
    push eax 
    push scan_fmt 
    call scanf       ; scanf (" %d", &c); 
    add esp, 8       ; Clean up the stack 

    lea eax, [in_msg+12] 
    push eax 
    call printf       ; printf ("d: "); 

    add esp, 4 
    lea eax, [.d]      ; Pointer to .a (effective address of .a) 
    push eax 
    push scan_fmt 
    call scanf       ; scanf (" %d", &d); 
    add esp, 8       ; Clean up the stack 

    push [.d]       ; Call by value 
    push [.c]       ; Call by value 
    push [.b]       ; Call by value 
    push [.a]       ; Call by value 
    call calc       ; EAX = calc (a,b,c,d) 
    add esp, 16       ; Clean up the stack 
    mov [.calculation], eax    ; Store result for later use 

    push [.calculation] 
    push out_fmt 
    call printf       ; printf("5*a-c*d+7*b-2=%d\n",calculation); 
    add esp,8       ; Clean up the stack 

    leave 
    ret 

section '.data' writeable 

    out_fmt  db "5*a-c*d+7*b-2=%d", 10, 0 
    scan_fmt db " %d",0 
    in_msg  db "a: ",0,"b: ",0,"c: ",0,"d: ",0 

Соберите, ссылку и запустить его с

fasm calc.asm 
g++ -m32 -o calc calc.o 
./calc 

Вместо g++ вы можете использование gcc.