Trang 1 trên tổng số 3 123 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 23 kết quả

Đề tài: Inline ASM gọi hàm!

  1. #1
    Ngày gia nhập
    01 2010
    Nơi ở
    до свидания!
    Bài viết
    1,766

    Mặc định Inline ASM gọi hàm!

    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:
    PHP Code:
    #include <iostream>
    #include <conio.h>
    using namespace std;

    int Tong(int aint b)
    {
        return (
    a+b);
    }

    int main()
    {
        
    int retValue;
        
    _asm
        
    {
            
    push 10        
            push 16
            call Tong    
    //Gọi hàm đây
            
    add esp8        
            mov retValue
    eax
        
    }

        
    cout << "Tong cua 10+16 = " << retValue;
        
    getch();
        return 
    0;

    Tại sao chúng ta phải inline ASM trong C/C++??? Sau một thời gian Peter tìm hiểu về ASM thì Peter bắt đầu muốn dùng ASM trong ngôn ngữ C/C++ _ Đơn giản vì bắt gặp một câu trả lời "bâng quơ" không giải thích là "mã ASM chạy nhanh hơn mã C/C++"; Peter hiểu là mã C/C++ sẽ được dịch thành mã máy, 1 câu lệnh mã C/C++ có thể sinh vài lệnh mã máy; nên Peter nghĩ rằng đây là lời giải đáp thiết thực cho câu trả lời bâng quơ trên.....
    Chúc các bạn học tốt!
    Đã được chỉnh sửa lần cuối bởi peterdrew : 29-06-2010 lúc 06:39 PM.

  2. #2
    Ngày gia nhập
    04 2009
    Nơi ở
    một căn hộ nhỏ trên trái đất
    Bài viết
    372

    @peterdrew: Thủ thuật thì anh cũng phải giải thích chứ.
    Chẳng hạn tại sao phải push 10, 16
    Tại sao phải add esp, 8, nếu ko làm thì có chuyện gì xảy ra.
    Being top programmers always requires advanced knowledge of C/C++ and assembly


  3. #3
    Ngày gia nhập
    05 2010
    Nơi ở
    Cách Mạng Tháng 8
    Bài viết
    205


    Hàm trong ASM sẽ lấy các đối số trong Stack nên phải push vào.

    Về lệnh add esp, 8 thì phải nói tới nguyên tắc dùng Stack của 1 hàm: trước khi thực hiên hàm , con trỏ Stack ờ đâu thì sau khi hàm thực hiện xong phải trả nó về đúng vị trí ấy.
    Con trỏ esp ở địa chỉ cao, khi push vào thì nó giảm xuống. Ở đây ta push 2 số int nên esp giảm 8 byte. Thay vì pop 2 lần mà chẳng cần sử dụng giá trị đó thì ta chỉ việc cộng esp với 8 để quay về vị trí cũ là được.
    Nothing last forever !!

  4. #4
    Ngày gia nhập
    01 2010
    Nơi ở
    до свидания!
    Bài viết
    1,766

    Trích dẫn Nguyên bản được gửi bởi Nature Master Xem bài viết

    Hàm trong ASM sẽ lấy các đối số trong Stack nên phải push vào.

    Về lệnh add esp, 8 thì phải nói tới nguyên tắc dùng Stack của 1 hàm: trước khi thực hiên hàm , con trỏ Stack ờ đâu thì sau khi hàm thực hiện xong phải trả nó về đúng vị trí ấy.
    Con trỏ esp ở địa chỉ cao, khi push vào thì nó giảm xuống. Ở đây ta push 2 số int nên esp giảm 8 byte. Thay vì pop 2 lần mà chẳng cần sử dụng giá trị đó thì ta chỉ việc cộng esp với 8 để quay về vị trí cũ là được.
    Hoàn toàn chuẩn! Lời giải đáp này đã giải quyết được các yêu cầu của Ictrack rồi; tuy nhiên trước khi đọc bài này thì các bạn cũng nên tìm hiểu cách làm việc của lệnh Add; hai thanh ghi esp (tại sao không dùng cái khác?!!! khi hiểu được tác dụng của thanh ghi này rồi thì việc thao tác phía sau mới dễ dàng được) và eax. Hy vọng các bạn tiếp tục trao đổi nếu cần thiết.
    p/s: Thật ra thì cái này Ic đã hiểu rồi, chỉ muốn Peter giải thích cho mọi người hiểu thôi! Tuy nhiên bạn Nature Master đã rõ ràng rồi, Peter không ý kiến thêm.

  5. #5
    Ngày gia nhập
    05 2010
    Nơi ở
    Cách Mạng Tháng 8
    Bài viết
    205

    Trích dẫn Nguyên bản được gửi bởi peterdrew Xem bài viết
    p/s: Thật ra thì cái này Ic đã hiểu rồi, chỉ muốn Peter giải thích cho mọi người hiểu thôi! Tuy nhiên bạn Nature Master đã rõ ràng rồi, Peter không ý kiến thêm.

    Thật ra thì chưa có "ma" nào hỏi cả, anh Peter ạ
    Nothing last forever !!

  6. #6
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,007

    Mặc định Inline ASM gọi hàm!

    @anh pt và Nature Master
    langman góp ý thế này :
    còn thiếu cân bằng si và sp nữa
    PHP Code:
    mov esi,esp
            push 10        
    //  b sẽ nhận giá trị này
            
    push 16        // a sẽ nhận giá trị này
            
    call Tong    //Gọi hàm đây
            
    add esp8        
            mov retValue
    eax 
    Đã được chỉnh sửa lần cuối bởi langman : 26-05-2010 lúc 05:08 PM.
    ^_,^

    Facebook : https://www.facebook.com/langmaninternet

    Bùi Tấn Quang

  7. #7
    Ngày gia nhập
    04 2009
    Nơi ở
    một căn hộ nhỏ trên trái đất
    Bài viết
    372

    @langman: esp đã được hồi phục sau khi gọi add esp, 8.
    Cất esp vào esi làm gì hả langman
    Being top programmers always requires advanced knowledge of C/C++ and assembly


  8. #8
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,007

    Trích dẫn Nguyên bản được gửi bởi icttrack Xem bài viết
    @langman: esp đã được hồi phục sau khi gọi add esp, 8.
    Cất esp vào esi làm gì hả langman
    ừa ha
    giờ mới để ý , nhưng như thế hình như ko được hay lắm
    + với 1 class thì phải tính toán độ lệch để nhảy về, mà như đã biết thì class tự làm tròn dung lượng lượng chia hết 4, như thế có thể tính nhầm,
    +trong quá trình call hàm thì lại phải lo lắng đến việc tạo sao chép
    +trong hàm có đệ quy hoặc *** mà có dùng dến đệ quy thì tính toán độ lệch kiểu gì



    phương án a pt đưa ra để hiểu thêm, rất hay, mà ko áp dụng vào thực tế , vì
    + bỏ qua sự biên dịch thông minh của trình biên dịch
    + kết quả cuối cùng giữa bt và của a cũng sinh mã gần giống nhau thôi mà, cái tiết kiệm được chỉ là chi phí về thời gian cho việc biên dịch
    ^_,^

    Facebook : https://www.facebook.com/langmaninternet

    Bùi Tấn Quang

  9. #9
    Ngày gia nhập
    04 2009
    Nơi ở
    một căn hộ nhỏ trên trái đất
    Bài viết
    372

    + với 1 class thì phải tính toán độ lệch để nhảy về, mà như đã biết thì class tự làm tròn dung lượng lượng chia hết 4, như thế có thể tính nhầm,
    +trong quá trình call hàm thì lại phải lo lắng đến việc tạo sao chép
    +trong hàm có đệ quy hoặc *** mà có dùng dến đệ quy thì tính toán độ lệch kiểu gì
    Mình thật sự không hiểu hết ý của langman. Nếu thủ tục trong ASM (hàm trong C/C++) được thiết lập stack frame (khung ngăn xếp) cẩn thận thì khi gọi đệ quy chẳng khỏi lo CPU tính toán sai vì mỗi lần gọi thủ tục thì thủ tục đã có một stack frame của riêng nó.
    Dùng đệ quy hay không đệ quy thì bản chất CPU sẽ nhảy đến địa chỉ chứa mã lệnh của thủ tục, nếu bị gọi đệ quy thì thực ra ta lại quay lại địa chỉ của thủ tục đó thôi khi mã lệnh của thủ tục đó còn chưa được chạy hết, về vấn đề này thì việc gọi thủ tục giống lệnh jump chỉ có điều nó sẽ cất nội dung của thanh ghi EIP chứa địa chỉ của lệnh tiếp theo sau lệnh gọi thủ tục vào trong ngăn xếp.

    phương án a pt đưa ra để hiểu thêm, rất hay, mà ko áp dụng vào thực tế , vì
    + bỏ qua sự biên dịch thông minh của trình biên dịch
    + kết quả cuối cùng giữa bt và của a cũng sinh mã gần giống nhau thôi mà, cái tiết kiệm được chỉ là chi phí về thời gian cho việc biên dịch
    Phương án của anh peter là cần thiết nếu ta muốn gọi hàm C, C++ (với chú ý là hàm C++ ko được phép nạp chồng) ngay trong mã assembly. Điều này là hoàn toàn có thể xảy ra vì ta muốn tối ưu một đoạn mã nào đó bằng việc viết asm, yêu cầu của đoạn mã đó là có sử dụng hàm viết bằng ngôn ngữ C hoặc C++ thì không có cách nào khác ngoài cách gọi kiểu như trên đối với thư viện trong C)
    Cần biết rằng cách gọi như anh peter lấy ví dụ là cách mà trong chương trình chúng ta gọi các hàm như printf, scanf trong thư viện C, vì hàm trong thư viện C sử dụng quy ước gọi __cdecl.
    Being top programmers always requires advanced knowledge of C/C++ and assembly


  10. #10
    Ngày gia nhập
    06 2007
    Nơi ở
    C:\WINDOWS\system32\dllcache\
    Bài viết
    3,007

    Trích dẫn Nguyên bản được gửi bởi icttrack Xem bài viết
    Mình thật sự không hiểu hết ý của langman. Nếu thủ tục trong ASM (hàm trong C/C++) được thiết lập stack frame (khung ngăn xếp) cẩn thận thì khi gọi đệ quy chẳng khỏi lo CPU tính toán sai vì mỗi lần gọi thủ tục thì thủ tục đã có một stack frame của riêng nó.
    Dùng đệ quy hay không đệ quy thì bản chất CPU sẽ nhảy đến địa chỉ chứa mã lệnh của thủ tục, nếu bị gọi đệ quy thì thực ra ta lại quay lại địa chỉ của thủ tục đó thôi khi mã lệnh của thủ tục đó còn chưa được chạy hết, về vấn đề này thì việc gọi thủ tục giống lệnh jump chỉ có điều nó sẽ cất nội dung của thanh ghi EIP chứa địa chỉ của lệnh tiếp theo sau lệnh gọi thủ tục vào trong ngăn xếp.


    Phương án của anh peter là cần thiết nếu ta muốn gọi hàm C, C++ (với chú ý là hàm C++ ko được phép nạp chồng) ngay trong mã assembly. Điều này là hoàn toàn có thể xảy ra vì ta muốn tối ưu một đoạn mã nào đó bằng việc viết asm, yêu cầu của đoạn mã đó là có sử dụng hàm viết bằng ngôn ngữ C hoặc C++ thì không có cách nào khác ngoài cách gọi kiểu như trên đối với thư viện trong C)
    Cần biết rằng cách gọi như anh peter lấy ví dụ là cách mà trong chương trình chúng ta gọi các hàm như printf, scanf trong thư viện C, vì hàm trong thư viện C sử dụng quy ước gọi __cdecl.
    cậu ko hiểu ý tớ rồi,
    trong bài đó ý tớ nói là
    bài của a pt để tìm hiểu sâu về bản chất của vấn đề, rất hay và nên biết
    nhưng mà để áp dụng vào thực tế tức là lúc code đổi lời gọi hàm bằng đoạn mã asm là ko khả thi vì những lý do tớ đưa ra đó, việc đặt lời gọi hàm vô sẽ khả thi hơn.
    ^_,^

    Facebook : https://www.facebook.com/langmaninternet

    Bùi Tấn Quang

Các đề tài tương tự

  1. Từ khóa inline dùng để làm gì?
    Gửi bởi mp121209 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 1
    Bài viết cuối: 07-05-2011, 08:00 PM
  2. Khác nhau giữa code inline và behind trong ASP.NET
    Gửi bởi sparkle trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 2
    Bài viết cuối: 27-03-2011, 10:15 AM
  3. Kỹ thuật C Sự khác nhau giửa inline function và macro trong C/C++????
    Gửi bởi 123456jindo trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 5
    Bài viết cuối: 11-03-2011, 11:05 PM
  4. Lập trình C++ Thắc mắc về tác dụng của hàm trực tuyến (inline)
    Gửi bởi cab8nwf6hgpc trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 5
    Bài viết cuối: 22-07-2010, 09:52 PM
  5. Linux Programming | Inline assembly
    Gửi bởi spacetime trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 2
    Bài viết cuối: 26-10-2007, 04:56 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn