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ố 27 kết quả

Đề tài: Hợp ngữ & Inline assembler

  1. #1
    Ngày gia nhập
    09 2016
    Bài viết
    1,028

    Mặc định Hợp ngữ & Inline assembler

    01. Mượn thay lời mở đầu

    In computer programming, the inline assembler is a feature of some compilers that allows low level code written in Assembly Language to be embedded within the existing program code that would have been created using a high level language like C or Ada. This embedding is usually done for one of three reasons:

    Optimization
    To use assembly language for inline optimization, programmers code the most performance-sensitive parts of their program's algorithms using hand-coded assembly language. This allows the programmer to use the full extent of their ingenuity, without being limited by a compiler's higher-level constructs.
    Access to processor specific instructions
    Some processors offer special instructions, such as Compare and Swap and Test and Set — instructions which may be used to construct semaphores or other synchronization and locking primitives. Nearly every modern processor has these or similar instructions, as they are necessary to implement multitasking. To name a few, specialized instructions are found in the SPARC VIS, Intel MMX and SSE, and Motorola Altivec instruction sets.
    System calls
    High-level languages rarely have a direct facility to make arbitrary system calls, so assembly code is used.

    Mại dzô, mời vô tham gia !

    Phọt mô xa 2016

  2. #2
    Ngày gia nhập
    09 2016
    Bài viết
    1,028

    02: Dùng công cụ chuyển c/c++ sang asm
    Lấy ví dụ bài toán tính Sin

    C++ Code:
    1. #include <stdio.h>
    2. #include <math.h>
    3.  
    4. #define EPSILON 0.0000001
    5. //#define mAbs(x) x>0?x:-x
    6. double sinCalc(const double x){
    7.     double kq = x, P = x; //P(k)
    8.     int k = 1;
    9.  
    10.     do{
    11.         P *= -x*x/(2*k)/(2*k+1); //P(k) = P(k-1)* df(k)
    12.         kq += P; //Sin(k) = Sin(k-1) + P(k)    
    13.         k++;
    14.     }
    15.     //while(P > EPSILON);
    16.     //while(mAbs(P) > EPSILON);
    17.     while((P>0?P:-P) > EPSILON);
    18.    
    19.     return kq;
    20. }
    21.  
    22. int main(){
    23.     double x, y;  
    24.     printf("\ninput x = "); scanf("%lf", &x);
    25.     //
    26.     y = sin(x);
    27.     printf("\n(Math) y = %f", y);
    28.     //
    29.     y = sinCalc(x);
    30.     printf("\n(Calc) y = %f", y);  
    31. }

    với borland c/c++ hay MinGW có thể dùng tùy chọn -S để chuyển (Xem các topic liên quan có trong diễn đàn)
    Vài trường hợp cần sửa kết quả bằng tay. Để thuận tiện cho các thành viên dùng Visual Studio, tôi chỉnh lại có thể biên dịch với vc:

    ASM Code:
    1. ;.686P
    2. ;.XMM
    3. .model  flat
    4.  
    5. INCLUDELIB LIBCMT
    6.  
    7. CONST   SEGMENT
    8. EPS DQ 03e7ad7f29abcaf48r   ; 1e-007
    9. sIn DB  0aH, 'input x = ', 00H
    10. sDd DB  '%lf', 00H
    11. sMath   DB  0aH, '(Math) y = %f', 00H
    12.     ORG $+1
    13. sCalc   DB  0aH, '(Calc) y = %f', 00H
    14. CONST   ENDS
    15.  
    16. ;===========
    17. _TEXT   SEGMENT
    18. goA = -40                       ; size = 8
    19. goB = -32                       ; size = 4
    20. goC = -28                       ; size = 4
    21. ;===
    22. kq = -24                        ; size = 8
    23. k = -12                     ; size = 4
    24. P = -8                      ; size = 8
    25. x = 8                       ; size = 8
    26. sinCalc PROC
    27. ; Line 7
    28.     push    ebp
    29.     mov ebp, esp
    30.     sub esp, 40                 ; 00000028H
    31. ; Line 8
    32.     fld QWORD PTR x[ebp]
    33.     fstp    QWORD PTR kq[ebp]
    34.     fld QWORD PTR x[ebp]
    35.     fstp    QWORD PTR P[ebp]
    36. ; Line 9
    37.     mov DWORD PTR k[ebp], 1
    38. LabA:
    39. ; Line 12
    40.     fld QWORD PTR x[ebp]
    41.     fchs
    42.     fmul    QWORD PTR x[ebp]
    43.     mov eax, DWORD PTR k[ebp]
    44.     shl eax, 1
    45.     mov DWORD PTR goC[ebp], eax
    46.     fild    DWORD PTR goC[ebp]
    47.     fdivp   ST(1), ST(0)
    48.     mov ecx, DWORD PTR k[ebp]
    49.     lea edx, DWORD PTR [ecx+ecx+1]
    50.     mov DWORD PTR goB[ebp], edx
    51.     fild    DWORD PTR goB[ebp]
    52.     fdivp   ST(1), ST(0)
    53.     fmul    QWORD PTR P[ebp]
    54.     fstp    QWORD PTR P[ebp]
    55. ; Line 13
    56.     fld QWORD PTR kq[ebp]
    57.     fadd    QWORD PTR P[ebp]
    58.     fstp    QWORD PTR kq[ebp]
    59. ; Line 14
    60.     mov eax, DWORD PTR k[ebp]
    61.     add eax, 1
    62.     mov DWORD PTR k[ebp], eax
    63. ; Line 18
    64.     fldz
    65.     fcomp   QWORD PTR P[ebp]
    66.     fnstsw  ax
    67.     test    ah, 5
    68.     jp  SHORT LabB
    69.     fld QWORD PTR P[ebp]
    70.     fstp    QWORD PTR goA[ebp]
    71.     jmp SHORT LabC
    72. LabB:
    73.     fld QWORD PTR P[ebp]
    74.     fchs
    75.     fstp    QWORD PTR goA[ebp]
    76. LabC:
    77.     fld QWORD PTR EPS
    78.     fcomp   QWORD PTR goA[ebp]
    79.     fnstsw  ax
    80.     test    ah, 5
    81.     jnp SHORT LabA
    82. ; Line 20
    83.     fld QWORD PTR kq[ebp]
    84. ; Line 21
    85.     mov esp, ebp
    86.     pop ebp
    87.     ret 0
    88. sinCalc ENDP
    89. _TEXT   ENDS
    90.  
    91. ;===========
    92. PUBLIC  _main
    93. EXTRN   _sin:PROC
    94. EXTRN   _scanf:PROC
    95. EXTRN   _printf:PROC
    96.  
    97. _TEXT   SEGMENT
    98. x = -16                     ; size = 8
    99. y = -8                      ; size = 8
    100. _main   PROC
    101. ; Line 23
    102.     push    ebp
    103.     mov ebp, esp
    104.     sub esp, 16                 ; 00000010H
    105. ; Line 25
    106.     push    OFFSET sIn
    107.     call    _printf
    108.     add esp, 4
    109.     lea eax, DWORD PTR x[ebp]
    110.     push    eax
    111.     push    OFFSET sDd
    112.     call    _scanf
    113. ; Line 27
    114.     fld QWORD PTR x[ebp]
    115.     fstp    QWORD PTR [esp]
    116.     call    _sin
    117.     add esp, 8
    118.     fstp    QWORD PTR y[ebp]
    119. ; Line 28
    120.     sub esp, 8
    121.     fld QWORD PTR y[ebp]
    122.     fstp    QWORD PTR [esp]
    123.     push    OFFSET sMath
    124.     call    _printf
    125. ; Line 30
    126.     add esp, 4
    127.     fld QWORD PTR x[ebp]
    128.     fstp    QWORD PTR [esp]
    129.     call    sinCalc
    130.     add esp, 8
    131.     fstp    QWORD PTR y[ebp]
    132. ; Line 31
    133.     sub esp, 8
    134.     fld QWORD PTR y[ebp]
    135.     fstp    QWORD PTR [esp]
    136.     push    OFFSET sCalc
    137.     call    _printf
    138.     add esp, 12                 ; 0000000cH
    139. ; Line 32
    140.     xor eax, eax
    141.     mov esp, ebp
    142.     pop ebp
    143.     ret 0
    144. _main   ENDP
    145. _TEXT   ENDS
    146.  
    147. ;===========
    148. END

    Biên dịch với MsVC 2010
    Batch Code:
    1. ml /c /Cx /coff SinAsm.asm
    2. link SinAsm.obj

    Phọt mô xa 2016

  3. #3
    Ngày gia nhập
    09 2016
    Bài viết
    1,028

    Trên trong SinAsm.asm các keyword, cấu trúc lặp, dataType mất đâu hết !

    03 : Dùng MinGW, gcc dựa theo bài viết:
    http://stackoverflow.com/questions/7190050/how-do-i-compile-the-asm-generated-by-gcc

    C Code:
    1. #include <stdio.h>
    2.  
    3. int main(){
    4.   printf("Hello world!\n");
    5.   return 0;
    6. }

    Biên dịch:
    Batch Code:
    1. gcc file.c -S -o file.S
    2.  
    3. gcc -c file.S -o file.o
    4. gcc file.o -o file
    5.  
    6. file.exe
    7. Hello world!

    file.s thu được (nguyên gốc, không sửa):
    ASM Code:
    1.     .file   "file.c"
    2.     .def    ___main;    .scl    2;  .type   32; .endef
    3.     .section .rdata,"dr"
    4. LC0:
    5.     .ascii "Hello world!\0"
    6.     .text
    7.     .globl  _main
    8.     .def    _main;  .scl    2;  .type   32; .endef
    9. _main:
    10.     pushl   %ebp
    11.     movl    %esp, %ebp
    12.     andl    $-16, %esp
    13.     subl    $16, %esp
    14.     call    ___main
    15.     movl    $LC0, (%esp)
    16.     call    _puts
    17.     movl    $0, %eax
    18.     leave
    19.     ret
    20.     .ident  "GCC: (tdm-1) 4.9.2"
    21.     .def    _puts;  .scl    2;  .type   32; .endef
    Nó tự tiện thay printf bằng puts

    Phọt mô xa 2016

  4. #4
    Ngày gia nhập
    09 2016
    Bài viết
    1,028

    04 : Sử dụng Borland c/c++
    Với bài toán "Nhập 1 số nguyên dương N, in ra số fibonacci nhỏ nhất Fib >= N"

    C Code:
    1. #include <stdio.h>
    2.  
    3. int main(){
    4.     int arF[]={
    5.     //Xem http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibtable.html,
    6.     //The first 300 Fibonacci numbers, factored
    7.     //...dãy 46 số đầu trong phạm vi int, next tràn số
    8.     };
    9.     int n, i = 0;
    10.    
    11.     printf("\nFind Fibonacci number, 0 <= n <= Fib, n = "); scanf("%d", &n);
    12.     //
    13.     if(n < 0) {
    14.         printf("\nError, input %d < 0", n);
    15.         return -1;
    16.     }
    17.    
    18.     while(n > arF[i])
    19.         i++;   
    20.     //
    21.     if(i > 46){
    22.         puts("\n\nError, Overflow !");
    23.         return 1;      
    24.     }
    25.     printf("\nFib[%d] is %d", i, arF[i]);
    26.    
    27.     return 0;
    28. }

    Biên dịch asm
    bcc32 Fibs.asm

    Hình minh hoạ biên dịch, chạy thử
    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		_Fibs.jpg
Lần xem:	7
Size:		55.8 KB
ID:		50858

    Phọt mô xa 2016
    Attached Files Attached Files

  5. #5
    Ngày gia nhập
    09 2016
    Bài viết
    1,028

    Nhiều người (các lập trình viên / bột/ nước) cho rằng c là ngôn ngữ nhanh nhất, rồi Asm còn nhanh hơn cả c. Có lẽ tiền đề này có sạn, không hoàn toàn đúng.

    Có lẽ asm ít người xài nên các trình biên dịch không chuyển đổi chính xác, đúng đắn khi biên dịch c/c++ sang asm, nhiều trường hợp cần sửa kết quả bằng tay (lổi biên dịch tiếp theo, asm sang obj/exec file). Hoặc nó sinh code sai logic làm kết quả không như mong đợi

    Cùng vấn đề như reply #2, dùng cl.exe dịch, có kết quả Sin.asm :
    ASM Code:
    1. .686P
    2. .XMM
    3. include listing.inc
    4. .model  flat
    5.  
    6. INCLUDELIB LIBCMT
    7. INCLUDELIB OLDNAMES
    8.  
    9. CONST   SEGMENT
    10. inA DB  0aH, 'input x = ', 00H
    11. inB DB  '%lf', 00H
    12. sMath   DB  0aH, '(Math) y = %f', 00H
    13.     ORG $+1
    14. sCalc   DB  0aH, '(Calc) y = %f', 00H
    15. CONST   ENDS
    16.  
    17. PUBLIC  EPS
    18. PUBLIC  unA
    19. PUBLIC  fnCalc              ; sinCalc
    20. EXTRN   __fltused:DWORD
    21.  
    22. CONST   SEGMENT
    23. EPS DQ 03e7ad7f29abcaf48r   ; 1e-007
    24. CONST   ENDS
    25.  
    26. CONST   SEGMENT
    27. unA DQ 00000000000000000r   ; 0
    28. CONST   ENDS
    29.  
    30. _TEXT   SEGMENT
    31. tv79 = -44                      ; size = 4
    32. tv81 = -40                      ; size = 8
    33. tv89 = -32                      ; size = 4
    34. tv87 = -28                      ; size = 4
    35. ;
    36. vKQ = -24                       ; size = 8
    37. vID = -12                       ; size = 4
    38. vPd = -8                        ; size = 8
    39. vMr = 8                         ; size = 8
    40.  
    41. fnCalc PROC                 ; sinCalc
    42. ; Line 6
    43.     push    ebp
    44.     mov ebp, esp
    45.     sub esp, 44                 ; 0000002cH
    46. ; Line 7
    47.     fld QWORD PTR vMr[ebp]
    48.     fstp    QWORD PTR vKQ[ebp]
    49.     fld QWORD PTR vMr[ebp]
    50.     fstp    QWORD PTR vPd[ebp]
    51. ; Line 8
    52.     mov DWORD PTR vID[ebp], 1
    53. Lab1:
    54. ; Line 11
    55.     fld QWORD PTR vMr[ebp]
    56.     fchs
    57.     fmul    QWORD PTR vMr[ebp]
    58.     mov eax, DWORD PTR vID[ebp]
    59.     shl eax, 1
    60.     mov DWORD PTR tv87[ebp], eax
    61.     fild    DWORD PTR tv87[ebp]
    62.     fdivp   ST(1), ST(0)
    63.     mov ecx, DWORD PTR vID[ebp]
    64.     lea edx, DWORD PTR [ecx+ecx+1]
    65.     mov DWORD PTR tv89[ebp], edx
    66.     fild    DWORD PTR tv89[ebp]
    67.     fdivp   ST(1), ST(0)
    68.     fmul    QWORD PTR vPd[ebp]
    69.     fstp    QWORD PTR vPd[ebp]
    70. ; Line 12
    71.     fld QWORD PTR vKQ[ebp]
    72.     fadd    QWORD PTR vPd[ebp]
    73.     fstp    QWORD PTR vKQ[ebp]
    74. ; Line 13
    75.     mov eax, DWORD PTR vID[ebp]
    76.     add eax, 1
    77.     mov DWORD PTR vID[ebp], eax
    78. ; Line 16
    79.     fldz
    80.     fcomp   QWORD PTR vPd[ebp]
    81.     fnstsw  ax
    82.     test    ah, 5
    83.     jp  SHORT Lab5
    84.     fld QWORD PTR vPd[ebp]
    85.     fstp    QWORD PTR tv81[ebp]
    86.     jmp SHORT Lab4
    87. Lab5:
    88.     fld QWORD PTR vPd[ebp]
    89.     fchs
    90.     fcomp   QWORD PTR EPS
    91.     fnstsw  ax
    92.     test    ah, 65                  ; 00000041H
    93.     jne SHORT Lab2
    94.     mov DWORD PTR tv79[ebp], 1
    95.     jmp SHORT Lab3
    96. Lab2:
    97.     mov DWORD PTR tv79[ebp], 0
    98. Lab3:
    99.     fild    DWORD PTR tv79[ebp]
    100.     fstp    QWORD PTR tv81[ebp]
    101. Lab4:
    102.     fld QWORD PTR tv81[ebp]
    103.     fldz
    104.     fucompp
    105.     fnstsw  ax
    106.     test    ah, 68                  ; 00000044H
    107.     jp  Lab1
    108. ; Line 18
    109.     fld QWORD PTR vKQ[ebp]
    110. ; Line 19
    111.     mov esp, ebp
    112.     pop ebp
    113.     ret 0
    114. fnCalc ENDP                 ; sinCalc
    115. _TEXT   ENDS
    116.  
    117. PUBLIC  _main
    118. EXTRN   _sin:PROC
    119. EXTRN   _scanf:PROC
    120. EXTRN   _printf:PROC
    121. _TEXT   SEGMENT
    122. xO = -16                        ; size = 8
    123. yO = -8                     ; size = 8
    124. _main   PROC
    125. ; Line 21
    126.     push    ebp
    127.     mov ebp, esp
    128.     sub esp, 16                 ; 00000010H
    129. ; Line 23
    130.     push    OFFSET inA
    131.     call    _printf
    132.     add esp, 4
    133. ; Line 24
    134.     lea eax, DWORD PTR xO[ebp]
    135.     push    eax
    136.     push    OFFSET inB
    137.     call    _scanf
    138. ; Line 26
    139.     fld QWORD PTR xO[ebp]
    140.     fstp    QWORD PTR [esp]
    141.     call    _sin
    142.     add esp, 8
    143.     fstp    QWORD PTR yO[ebp]
    144. ; Line 27
    145.     sub esp, 8
    146.     fld QWORD PTR yO[ebp]
    147.     fstp    QWORD PTR [esp]
    148.     push    OFFSET sMath
    149.     call    _printf
    150. ; Line 29
    151.     add esp, 4
    152.     fld QWORD PTR xO[ebp]
    153.     fstp    QWORD PTR [esp]
    154.     call    fnCalc          ; sinCalc
    155.     add esp, 8
    156.     fstp    QWORD PTR yO[ebp]
    157. ; Line 30
    158.     sub esp, 8
    159.     fld QWORD PTR yO[ebp]
    160.     fstp    QWORD PTR [esp]
    161.     push    OFFSET sCalc
    162.     call    _printf
    163.     add esp, 12                 ; 0000000cH
    164. ; Line 31
    165.     xor eax, eax
    166.     mov esp, ebp
    167.     pop ebp
    168.     ret 0
    169. _main   ENDP
    170. _TEXT   ENDS
    171. END

    biên dịch asm sang exe:
    CMD Code:
    1. ml /c /Cx /coff Sin.asm
    2. link Sin.obj
    3. Sin.exe

    Nó chạy rất ẹ, chừng 10 giây sau nó mới hiện dấu nhắc:
    input x = _

    Phọt mô xa 2016

  6. #6
    Ngày gia nhập
    09 2016
    Bài viết
    1,028

    Mặc định Hợp ngữ & Inline assembler

    Cái học nhà nho đã hỏng rồi,
    Mười người đi học, chín người thôi.
    Cô hàng bán sách lim-dim ngủ,
    Thầy khóa tư lương nhấp-nhỏm ngồi.
    Sĩ-khí rụt-rè gà phải cáo,
    Văn-chương liều-lĩnh đấm ăn xôi.
    Tôi đâu dám mỉa làng tôi nhỉ?
    Trình có quan-tiên thứ-chỉ tôi.
    -Trần Tế Xương

    Thay "học nhà nho" bằng assembly cũng tàm tạm

    Phôt mô xa 2016

  7. #7
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    874

    Ao thu lạnh lẽo nước trong veo
    Một chiếc thuyền câu bé tẻo teo
    Sóng biếc theo làn hơi gợn tí
    Lá vàng trước gió bỗng bay vèo

    ...

    Thơ chế - Xin lỗi nhà thơ Nguyễn Khuyến

  8. #8
    Ngày gia nhập
    09 2016
    Bài viết
    1,028

    Theo tôi Assembly là cực kỳ quan trọng,
    - nó giúp bạn hiểu ý tưởng của người khác.
    - nó giúp bạn làm đúng như ý bạn nghĩ

    Nó không phải chỉ học cho biết, theo giáo trình của mấy tay mọt sách

    Phọt mô xa 2016

  9. #9
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    874

    Theo tôi thì không phải Cái học nhà nho đã hỏng rồi, mà phần lớn các bạn trẻ sau này ít tìm đến nó hoặc chỉ học để nhanh chóng tìm việc ngay sau vài năm mài ghế ĐH, thôi thì đấy là quyền của mỗi người.
    Phần khác nữa là những người chú tâm vào cấp thấp thường rất dè dặt khi phát biểu ý kiến, bởi họ rất hiểu những sai sót không ngờ. Bạn đã từng ở thời kỳ Windows còn sài ké từ DOS nên chắc biết hồi đó người ta đánh giá 1 LTV hệ thống trung bình ngày viết chưa tới 10 lệnh hợp ngữ đã là khá rồi.

    Vấn đề là bây giờ bạn chỉ ra những cái, những ví dụ nhỏ mà các NN bậc cao không làm được thì các bạn khác mới thấy được sự thiết thực, còn không thì :
    _ Tôi có thấy gì hay đâu, trên C# nháy mắt là làm được.
    _ Việc gì phải tốn công, gooooogo cái là có.
    _ Khô khan vậy, chẳng có gì bay bướm cả.

  10. #10
    Ngày gia nhập
    09 2016
    Bài viết
    1,028

    Có cách trả lời khác cho câu hỏi cũ.

    Khác là phương pháp tiếp cận. Cụ thể vấn đề tôi trình bày ở trên, bạn thấy nó nằm trong tài liệu nào chưa. Đó là công sức của chính tôi, không hề của bất cứ thày bà nào truyền đạt cả.

    Phọt mô xa 2016

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