Gia sư Cần Thơ, Dạy Kèm Cần Thơ

VỮNG TIN - TIẾP BƯỚC - THÀNH CÔNG


Inline ASM tính tổng hai số

Share
avatar
peterdrew
Nhập môn
Nhập môn

Tổng số bài gửi : 19
Points : 25
Join date : 09/07/2010
Age : 34
Đến từ : Viện Vũ khí_Bộ Quốc phòng

Inline ASM tính tổng hai số

Bài gửi  peterdrew on Fri Jul 09, 2010 8:38 pm

Peter mở ra vấn đề này cũng là vì giới thiệu với các bạn một vài code Inline ASM trong C/C++; với bài này Peter cho các bạn thấy một ví dụ đơn giản như tính tổng của 2 số thực (float) chẳng hạn:
Code:
#include <conio.h>
#include <stdio.h>
float a,b,tong;
int main()
{
    printf("Nhap vao so thu nhat, a= ");
    scanf("%f",&a);
    printf("Nhap vao so thu 2, b= ");
    scanf("%f",&b);
    _asm
    {
        fld a
            fld b
            fadd ST,ST(1)
            fstp tong
            fwait
    }
    printf("Tong cua hai so %f va %f la %f",a,b,tong);
    getch();
    return 0;
}

Hay cũng có thể làm như thế này (với số nguyên (int) có thêm các thao tác Trừ, Nhân và Chia):
Code:
#include <stdio.h>
#include <conio.h>

int Cong(int x, int y)
{
    __asm
    {
        mov eax,x;
        mov ebx,y;
        add eax,ebx;
        mov x,eax;
    }
    return x;
}

int Tru(int x, int y)
{
    __asm
    {
        mov eax,x;
        mov ebx,y;
        sub eax,ebx;
        mov x,eax;
    }
    return x;
}


int Chia(int x, int y)
{
    __asm
    {
        mov eax,x;
        mov ecx,y;
        sub edx,edx;
        div ecx;
        mov x,eax;
    }
    return x;
}

int Nhan(int x, int y)
{
    __asm
    {
        mov eax,x;
        mov ebx,y;
        mul ebx;
        mov x,eax;
    }
    return x;
}

int main ()
{
    int func;
    int x,y;
    bool finish=false;
   
    while (finish==false)
    {
        printf("1: Cong, 2: Tru, 3: Chia, 4: Nhan\n");
        printf("Lua chon:\n");
        scanf("%d",&func);
        printf("Nhap so hang dau tien:\n");
        scanf("%d",&x);
        printf("Nhap so hang thu hai:\n");
        scanf("%d",&y);
       
        switch(func)
        {
        case 1:
            printf("Tong %d va %d la: ",x,y,Cong(x,y));
            break;
        case 2:
            printf("Hieu %d cho %d la: ",x,y,Tru(x,y));
            break;
        case 3:
            printf("Thuong nguyen %d chia %d la: ",x,y,Chia(x,y));
            break;
        case 4:
            printf("Tich %d va %d la: ",x,y,Nhan(x,y));
            break;
        }
    }
    return 0;
}


Hoặc Inline chuẩn:
Code:
extern  "C" __declspec(naked)  int  __stdcall  Cong(int x, int y)

{
    _asm
    {     
        mov eax, dword ptr [esp+4]
        add eax, dword ptr [esp+8]
        ret 8
    }
}


extern "C" __declspec(naked)  int  __stdcall Tru(int x, int y)
{
    _asm
    {     
        mov eax, dword ptr [esp+4]
        sub eax, dword ptr [esp+8]
        ret 8
    }
}


extern "C" __declspec(naked)  int  __stdcall Chia(int x, int y)
{
    _asm
    {
        mov eax, dword ptr [esp+4] 
        cdq
        mov ecx, dword ptr [esp+8] 
        div ecx                   
        ret 8
    }
}

extern "C" __declspec(naked)  int  __stdcall Nhan(int x, int y)
{
    _asm
    {
        mov eax, dword ptr [esp+4]
        mul dword ptr [esp+8]
        ret 8
    }
 
}
Vậy các bạn thấy thế nào???


Được sửa bởi peterdrew ngày Sun Sep 05, 2010 3:30 pm; sửa lần 1.
avatar
peterdrew
Nhập môn
Nhập môn

Tổng số bài gửi : 19
Points : 25
Join date : 09/07/2010
Age : 34
Đến từ : Viện Vũ khí_Bộ Quốc phòng

Inline ASM trong main() để gọi hàm đã được viết bằng C/C++

Bài gửi  peterdrew on Fri Jul 09, 2010 8:49 pm

Sau khi xây dựng một hàm bằng ngôn ngữ C/C++ chuẩn, chúng ta có thể dùng hàm này trong inline ASM của C/C++; sau đây là chương trình tính tổng 2 số 10 và 16 chẳng hạn:
Code:
#include <stdio.h>
#include <conio.h>
//Xây dựng hàm tính Tổng hai số nguyên
int Tong(int a, int b)
{
    return (a+b);
}

int main()
{
    int retValue;
    _asm
    {
        push 10       
        push 16
        call Tong    //Gọi hàm Tổng đã được xây dựng ở trên!
        add esp, 8       
        mov retValue, eax
    }

    printf("Tong cua 10+16 = %d",retValue);
    getch();
    return 0;


Được sửa bởi peterdrew ngày Fri Jul 09, 2010 8:49 pm; sửa lần 1. (Reason for editing : Đặt code vào thẻ!)

pearlz
Nhập môn
Nhập môn

Tổng số bài gửi : 4
Points : 6
Join date : 11/07/2010

Re: Inline ASM tính tổng hai số

Bài gửi  pearlz on Sun Sep 05, 2010 1:09 am

Hê hê có cơ hội trả đòn bác peter rồi nhé!
cái inline asm thứ 3 có nghĩa là với int thì bác peter có lẽ hơi nhầm theo em phải là idiv và imul
vì trường hợp này bác dùng là int chứ không phải unsigned int
lí do là int thì có thể chứa cả giá trị dương (+, >0) và âm (-,<0)
bit trên cùng nhất sẽ dùng để chứa dấu chứ không dùng để chứa giá trị
nên khi ta dùng mul và div thì sẽ không có xét dấu và kết quả là không chính xác vì bit dấu bị đem ra để tính giá trị

pm: 2 Peterdrew em là perfect bên caulacbovb.net đã từng bị ăn 1 đòn của bác, hế hế hòa nhé, cho em kết bạn với bác peter nhé
yahoo của em là : hoanlevan22 khi nào bác rảnh thì buzz em tiếng nhé!
avatar
peterdrew
Nhập môn
Nhập môn

Tổng số bài gửi : 19
Points : 25
Join date : 09/07/2010
Age : 34
Đến từ : Viện Vũ khí_Bộ Quốc phòng

Re: Inline ASM tính tổng hai số

Bài gửi  peterdrew on Sun Sep 05, 2010 3:40 pm

pearlz đã viết:Hê hê có cơ hội trả đòn bác peter rồi nhé!
cái inline asm thứ 3 có nghĩa là với int thì bác peter có lẽ hơi nhầm theo em phải là idiv và imul
vì trường hợp này bác dùng là int chứ không phải unsigned int
lí do là int thì có thể chứa cả giá trị dương (+, >0) và âm (-,<0)
bit trên cùng nhất sẽ dùng để chứa dấu chứ không dùng để chứa giá trị
nên khi ta dùng mul và div thì sẽ không có xét dấu và kết quả là không chính xác vì bit dấu bị đem ra để tính giá trị

pm: 2 Peterdrew em là perfect bên caulacbovb.net đã từng bị ăn 1 đòn của bác, hế hế hòa nhé, cho em kết bạn với bác peter nhé
yahoo của em là : hoanlevan22 khi nào bác rảnh thì buzz em tiếng nhé!
Khi nhân thì chẳng cần imul; khi chia thì đúng là Peter chưa để ý cái idiv, thank cậu! Bài này post lâu mà bữa nay mới có cậu trả lời đó....
Code:
#include <stdio.h>
#include <conio.h>
extern "C" __declspec(naked)  int  __stdcall Nhan(int x, int y)
{
    _asm
    {
        mov eax, dword ptr [esp+4]
         mul dword ptr [esp+8]
         ret 8
    }
}
int main()
{
   int i,j;
   printf("i= ");
   scanf("%d",&i);
   printf("j= ");
   scanf("%d",&j);
    printf("%d * %d = %d",i,j,Nhan(i,j));
   getch();
   return 0;   
}

p/s: Còn cái chuyện bên clbvb chẳng có gì cả, Peter thấy quá bình thường!.... Cậu cũng có cá tính phết nhỉ??? Hì hì

Sponsored content

Re: Inline ASM tính tổng hai số

Bài gửi  Sponsored content


    Hôm nay: Tue Oct 17, 2017 9:49 pm