我有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
你能帮我在Assembly(没有C ++程序)中做输入输出吗?我不知道在这个例子中该怎么做。 感谢任何帮助。
答案 0 :(得分:0)
您可以在汇编代码中使用C库(libc)中的函数。详细说明如何调用C函数取决于使用哪个汇编程序。还有哪些寄存器和/或堆栈用于函数参数,其顺序取决于可执行目标(32位或64位)。例如,用于在64位Linux上调用scanf函数的yasm汇编语法可以是:
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
我建议使用gcc
代替ld
,因为gcc默认链接C库。
答案 1 :(得分:0)
在装配中手动编程cin
和cout
几乎是不可能的。但是你可以使用C库的函数printf
和scanf
,它是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
。