Làm thế nào để học hỗ trợ lắp ráp trong lập trình? [đóng cửa]


132

Tôi đã lập trình bằng các ngôn ngữ cấp cao hơn (Python, C #, VBA, VB.NET) trong khoảng 10 năm và tôi hoàn toàn không hiểu gì về những gì đang diễn ra, "dưới mui xe."

Tôi đang tự hỏi những lợi ích của việc học lắp ráp là gì, và nó sẽ hỗ trợ tôi như một lập trình viên như thế nào? Bạn có thể vui lòng cung cấp cho tôi một tài nguyên sẽ cho tôi thấy chính xác mối liên hệ giữa những gì tôi viết bằng mã cấp cao hơn với những gì xảy ra trong lắp ráp không?


2
Nếu bạn thực sự muốn biết những gì nằm sâu dưới mã của mình, hãy xem hướng dẫn sử dụng bộ xử lý Intel (chỉ phần giới thiệu): download.intel.com/products/ Processor /man / 310462.pdf . Có thể điều này sâu hơn một chút so với bạn muốn, nhưng tôi thấy nó hữu ích.
superM

4
Nếu bạn muốn biết những gì xảy ra dưới mui xe cụ thể trong .Net, bạn có thể muốn tìm hiểu thêm về CIL. Nó tương tự như lắp ráp theo một số cách, nhưng mức độ cao hơn nhiều. Do đó, nó dễ hiểu hơn lắp ráp thực tế.
Svick

6
Nếu bạn học lắp ráp, bạn có thể tránh nghĩ rằng bạn đang tối ưu hóa một forvòng lặp bằng cách khai báo các biến bên ngoài nó. ví dụ
StriplingWar Warrior

7
Ôi chúa ơi. Bạn vừa nhắc tôi về lớp học ngôn ngữ hội tôi đã học đại học khoảng 1 năm trước. Thật đáng kinh ngạc khi thấy những thứ cực kỳ đơn giản mà chúng ta coi là được dịch trong hàng trăm hoặc thậm chí hàng ngàn hoạt động cấp thấp hơn và nhỏ hơn. Máy tính là những cỗ máy phi thường.
Radu Murzea

14
Học lắp ráp sẽ ban cho bạn một tình yêu sâu sắc và bền bỉ đối với khái niệm ngôn ngữ lập trình bảo vệ bạn khỏi EVER phải viết lại mã phức tạp.
Shadur

Câu trả lời:


188

Bởi vì bạn sẽ hiểu nó thực sự hoạt động như thế nào .

  • Bạn sẽ hiểu rằng các lệnh gọi hàm không miễn phí và tại sao ngăn xếp cuộc gọi có thể bị tràn (ví dụ: trong các hàm đệ quy). Bạn sẽ hiểu làm thế nào các đối số được truyền cho các tham số hàm và các cách có thể được thực hiện (sao chép bộ nhớ, trỏ vào bộ nhớ).
  • Bạn sẽ hiểu rằng bộ nhớ không miễn phí và quản lý bộ nhớ tự động có giá trị như thế nào. Bộ nhớ không phải là thứ mà bạn "chỉ có", trong thực tế, nó cần được quản lý, chăm sóc và quan trọng nhất là không bị lãng quên (vì bạn cần tự giải phóng nó).
  • Bạn sẽ hiểu làm thế nào dòng điều khiển hoạt động ở mức cơ bản nhất.
  • Bạn sẽ đánh giá cao các cấu trúc trong các ngôn ngữ lập trình cấp cao hơn.

Những gì nó rút ra là tất cả những điều chúng ta viết bằng C # hoặc Python cần được dịch thành một chuỗi các hành động cơ bản mà máy tính có thể thực hiện. Thật dễ dàng để nghĩ về một máy tính về các lớp học, khái quát và hiểu danh sách nhưng chúng chỉ tồn tại trong các ngôn ngữ lập trình cấp cao của chúng tôi.

Chúng ta có thể nghĩ về các cấu trúc ngôn ngữ trông rất đẹp nhưng điều đó không chuyển dịch tốt sang cách làm việc cấp thấp. Bằng cách biết làm thế nào nó thực sự hoạt động, bạn sẽ hiểu rõ hơn tại sao mọi thứ hoạt động theo cách họ làm.


12
+1 cho "Bạn sẽ đánh giá cao các cấu trúc trong các ngôn ngữ lập trình cấp cao hơn" một mình. Câu trả lời chính xác.
DevSolo

42
Ngoại trừ sau vài tuần hoạt động, bạn sẽ bắt đầu nghĩ về C như một ngôn ngữ lập trình cấp cao. Trừ khi bạn đang nói chuyện với các nhà phát triển thiết bị nhúng cấp thấp, nói rằng to tiếng sẽ khiến hầu hết mọi người nghĩ rằng bạn hơi điên rồ.
Dan Neely

19
@Dan: Thật buồn cười khi những điều khoản này thay đổi theo thời gian. 20 năm trước, khi tôi bắt đầu lập trình, nếu bạn hỏi ai đó rằng họ sẽ nói "Tất nhiên C là ngôn ngữ cấp cao!" Điều đó nên rõ ràng; nó cung cấp một mô hình truy cập bộ nhớ và bộ nhớ chuẩn. Và đó là một sự trừu tượng hóa nghiêm trọng khỏi phần cứng; trong một ngôn ngữ cấp thấp, bạn phải tự theo dõi tất cả các địa chỉ bộ nhớ hoặc nếu bạn đang làm điều gì đó thực sự lạ mắt, bạn hãy viết phân bổ heap của riêng bạn! Vì vậy, tôi phải tự hỏi, những tiêu chí làm cho một cái gì đó cấp cao hoặc cấp thấp ngày nay là gì?
Mason Wheeler

9
Cấp cao / cấp thấp không phải là nhị phân. Một lập trình viên toàn diện, người đã viết cả lắp ráp và Python trong sự nghiệp của mình có thể coi C hoặc C ++ là ngôn ngữ trung cấp.
Russell Borogove

6
Đó là những điều quan trọng để hiểu, nhưng chúng dễ dàng được trình bày ở mức độ trừu tượng: ví dụ: trong một khóa học giới thiệu về máy tính ở cấp độ hướng dẫn máy. Tôi không phải là lập trình viên lắp ráp nhưng tôi hiểu họ rất rõ, nếu tôi tự nói như vậy. Trong một số câu trả lời SO tôi thấy thảo luận về bộ đệm và đường ống dẫn hướng, và những điều đó thực sự khiến đầu óc tôi quay cuồng; nhưng mức độ hướng dẫn phụ này (cho đến nay) bị thiếu trong các câu trả lời. Vì vậy, lợi ích của việc học lập trình lắp ráp thực sự là gì, trái ngược với việc tham gia một khóa học cơ bản?
alexis

33

Nó sẽ cho bạn hiểu rõ hơn về những gì "xảy ra dưới mui xe" và cách con trỏ hoạt động cũng như ý nghĩa của các biến đăng ký và kiến ​​trúc (phân bổ và quản lý bộ nhớ, truyền tham số (theo giá trị / theo tham chiếu), v.v.) nói chung.

Để xem nhanh với C thế nào đây?

#include <stdio.h>

main()
{
  puts("Hello World.");
  return(0);
}

biên dịch với gcc -S so.cvà hãy xem đầu ra lắp ráp trong so.s:

 $ cat so.s

    .file   "so.c"
    .section    .rodata
.LC0:
    .string "Hello World."
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $.LC0, (%esp)
    call    puts
    movl    $0, %eax
    leave
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

2
+1: Mẹo hay! Bạn có thể học được rất nhiều bằng cách xem trình biên dịch C làm gì.
Giorgio

8
... Có phải SOS cố ý? (gọi để được giúp đỡ, v.v.)
Izkata

1
@Izkata ha ha .. tốt, tôi thậm chí không nhận ra điều đó. Tôi có một so.ctệp tiêu chuẩn cho các câu hỏi stackoverflow (như tôi có so.py, so.awkv.v.) để kiểm tra mọi thứ một cách nhanh chóng. Vì vậy, .. :)
Levon

9
Nếu bạn biên dịch với gcc -O -c -g -Wa,-ahl=so.s so.cbạn có thể thấy đầu ra lắp ráp cho từng dòng mã C. Điều này làm cho nó dễ dàng hơn một chút để hiểu những gì đang xảy ra.
Mackie Messer

1
Có, đầu ra là dài. Bạn có thể tìm kiếm 5:so.cđể tìm mã cho dòng 5 của so.c.
Mackie Messer

30

Tôi nghĩ rằng câu trả lời bạn tìm kiếm là ở đây: http://www.codeproject.com/Articles/89460/Why-Learn-Assugging-L Language

Một trích dẫn từ bài báo:

Mặc dù đó là sự thật, nhưng có lẽ bạn sẽ không thấy mình viết ứng dụng của khách hàng tiếp theo trong quá trình lắp ráp, vẫn còn nhiều thứ để kiếm được từ việc học lắp ráp. Ngày nay, ngôn ngữ lắp ráp được sử dụng chủ yếu để thao tác phần cứng trực tiếp, truy cập vào các hướng dẫn của bộ xử lý chuyên dụng hoặc để giải quyết các vấn đề hiệu suất quan trọng. Sử dụng điển hình là trình điều khiển thiết bị, hệ thống nhúng cấp thấp và hệ thống thời gian thực.

Thực tế của vấn đề là, các ngôn ngữ cấp cao càng phức tạp và càng có nhiều ADT (loại dữ liệu trừu tượng) được viết, thì càng có nhiều chi phí phát sinh để hỗ trợ các tùy chọn này. Trong các trường hợp của .NET, có lẽ là MSIL cồng kềnh. Hãy tưởng tượng nếu bạn biết MSIL. Đây là nơi ngôn ngữ lắp ráp tỏa sáng.

Ngôn ngữ hội gần với bộ xử lý như bạn có thể nhận được như một lập trình viên, vì vậy một thuật toán được thiết kế tốt sẽ rất tuyệt - lắp ráp rất tốt để tối ưu hóa tốc độ. Đó là tất cả về hiệu suất và hiệu quả. Ngôn ngữ hội cho phép bạn kiểm soát hoàn toàn các tài nguyên của hệ thống. Giống như một dây chuyền lắp ráp, bạn viết mã để đẩy các giá trị đơn vào các thanh ghi, xử lý trực tiếp các địa chỉ bộ nhớ để lấy các giá trị hoặc con trỏ.

Viết trong lắp ráp là để hiểu chính xác làm thế nào bộ xử lý và bộ nhớ làm việc cùng nhau để "làm cho mọi thứ xảy ra". Được cảnh báo, ngôn ngữ lắp ráp là khó hiểu và kích thước mã nguồn của ứng dụng lớn hơn nhiều so với ngôn ngữ cấp cao. Nhưng đừng nhầm lẫn về điều đó, nếu bạn sẵn sàng dành thời gian và nỗ lực để làm chủ lắp ráp, bạn sẽ trở nên tốt hơn, và bạn sẽ trở thành một người nổi bật trong lĩnh vực này.

Ngoài ra, tôi muốn giới thiệu cuốn sách này vì nó có phiên bản đơn giản về kiến ​​trúc máy tính: Giới thiệu về Hệ thống máy tính: Từ Bits và Gates đến C và Beyond, 2 / e Yale N. Patt, Đại học Texas tại Austin Sanjay J. Patel, Đại học Illinois tại Urbana-Champaign


7
Điều này mô tả ASM được sử dụng cho mục đích gì và đề cập rằng HLL bị cồng kềnh, nhưng lợi ích cụ thể duy nhất được đưa ra khi học ASM là viết mã siêu nhanh. Có, nhưng ngay cả khi bạn học ASM, khả năng bạn thực sự kết hợp nó trong các ứng dụng như thế nào? Giả sử bạn viết ứng dụng kinh doanh, không phải bộ điều khiển phần cứng hoặc trình điều khiển thiết bị.

+1 @notkilroy, cảm ơn vì liên kết và đặc biệt là giới thiệu sách
Anthony

2
@Jon, tôi thực sự không thấy lý do tại sao bạn sẽ phát triển phần mềm kinh doanh. Đó là một điều nếu bạn là một DBA, hoặc viết một trình biên dịch, hoặc có không gian bộ nhớ hạn chế, nhưng tôi không nghĩ nhiều người thường xuyên chạm vào nó. Tối ưu hóa chủ yếu được chăm sóc bởi trình biên dịch, đó là lý do lớn nhất để viết trong lắp ráp. Đôi khi nó giúp khi theo dõi rò rỉ bộ nhớ.
Brynne

Vì tôi chuyên phát triển các ứng dụng kinh doanh, tôi chủ yếu dựa vào các công cụ phát triển ứng dụng dựa trên SQL sử dụng 4GL. Chúng cho phép tôi nhanh chóng tạo nguyên mẫu một ứng dụng và tùy chỉnh nó thành một hệ thống sản xuất. Hiếm khi tôi cần phải viết một cfunc có thể gọi được. Thời gian để cung cấp và thời gian để sửa đổi là những yếu tố lớn trong thế giới của tôi!
Frank R.

2
Tôi khá không đồng ý. Một trình tối ưu hóa tự động thường có thể đánh bại một lập trình viên con người trong việc tạo ra sự lắp ráp nhanh chóng.
DeadMG

22

Theo ý kiến ​​khiêm tốn của tôi, nó không giúp được gì nhiều.

Tôi đã từng biết x86 lắp ráp rất tốt. Nó đã giúp một chút khi lắp ráp trong các khóa học của tôi, nó đã xuất hiện một lần trong một cuộc phỏng vấn và nó giúp tôi chứng minh rằng một trình biên dịch (Metrowerks) đang tạo ra mã xấu. Thật thú vị khi máy tính thực sự hoạt động và tôi cảm thấy giàu hơn về mặt trí tuệ vì đã học nó. Nó cũng rất vui khi chơi cùng lúc đó.

Tuy nhiên, trình biên dịch ngày nay tốt hơn trong việc tạo lắp ráp hơn hầu hết mọi người trên hầu hết mọi đoạn mã. Trừ khi bạn đang viết một trình biên dịch hoặc kiểm tra xem trình biên dịch của bạn đang làm đúng hay không, bạn có thể đang lãng phí thời gian của mình bằng cách học nó.

Tôi thừa nhận rằng nhiều câu hỏi mà các lập trình viên C ++ vẫn hỏi một cách hữu ích được thông báo bằng cách biết lắp ráp. Ví dụ: tôi nên sử dụng biến stack hay heap? Tôi nên vượt qua bởi giá trị hoặc bởi tham chiếu const? Tuy nhiên, trong hầu hết các trường hợp, tôi nghĩ rằng những lựa chọn này nên được thực hiện dựa trên khả năng đọc mã thay vì tiết kiệm thời gian tính toán. (Ví dụ: sử dụng biến stack bất cứ khi nào bạn muốn giới hạn biến trong phạm vi.)

Đề nghị khiêm tốn của tôi là tập trung vào các kỹ năng thực sự quan trọng: thiết kế phần mềm, phân tích thuật toán và giải quyết vấn đề. Với kinh nghiệm phát triển các dự án lớn, trực giác của bạn sẽ được cải thiện, điều này làm tăng giá trị của bạn hơn nhiều so với việc biết lắp ráp (theo ý kiến ​​của tôi).


2
Tôi không đồng ý. Nếu bạn có kiến ​​thức sâu rộng về một thuật toán nhất định và nắm bắt tốt phần cứng, thường có thể tạo mã lắp ráp được tối ưu hóa tốt hơn so với những gì trình biên dịch có thể tạo vì nó phải chơi an toàn. Biết đại khái cách mã của bạn được dịch thành assembly cũng giúp ích khi thực hiện tối ưu hóa.
Leo

Tối ưu hóa không phải là lý do để tìm hiểu nó. Ở khía cạnh đó, tôi đồng ý với Neil G. Tuy nhiên, Neil G đang thiếu điểm; Anh ta đang đánh giá thấp cách thức nắm bắt cơ bản của anh ta về cỗ máy thực sự cho biết anh ta sử dụng ngôn ngữ cấp cao như thế nào.
Warren P

Theo kinh nghiệm của tôi, một thuật toán được thực hiện nhanh chóng bằng cách thực hiện nó, đo lường mọi thứ, tìm cách tối ưu hóa nó, thực hiện một cách tốt hơn, v.v. Vấn đề với lắp ráp là phải mất nhiều thời gian để thực hiện, vì vậy bạn sẽ không có cơ hội sàng lọc lặp đi lặp lại.
gnasher729

Có rất ít trường hợp để mã hóa lắp ráp ngày nay, nhưng biết cách nó hoạt động đơn giản là vô giá và sẽ giúp ích rất nhiều cho những ai muốn biết làm thế nào nó hoạt động. Tôi, ví dụ, thấy khó theo dõi mọi thứ khi tôi không biết tại sao nó lại xảy ra.
Cầu thủ chạy cánh Sendon

21

Bạn nên làm quen với một cấp độ 'sâu hơn' trong hệ thống mà bạn đang làm việc. Bỏ qua quá xa trong một lần không phải là xấu, nhưng có thể không hữu ích như người ta mong muốn.

Một lập trình viên trong một ngôn ngữ cấp cao nên học một ngôn ngữ cấp thấp hơn (C là một lựa chọn tuyệt vời). Bạn không cần phải tìm cách lắp ráp để có sự đánh giá cao những gì diễn ra dưới vỏ bọc khi bạn bảo máy tính khởi tạo một đối tượng hoặc tạo bảng băm hoặc một bộ - nhưng bạn sẽ có thể viết mã họ

Đối với một lập trình viên java, học một số C sẽ giúp bạn quản lý bộ nhớ, truyền các đối số. Viết một số thư viện java mở rộng trong C sẽ giúp hiểu được khi nào nên sử dụng triển khai Set nào (bạn có muốn băm không? Hoặc cây?). Xử lý char * trong môi trường luồng sẽ giúp hiểu tại sao String là bất biến.

Được đưa lên cấp độ tiếp theo ... Lập trình viên AC nên có một số quen thuộc với lắp ráp và các loại lắp ráp (được tìm thấy trong các cửa hàng hệ thống nhúng) có thể sẽ làm tốt với việc hiểu mọi thứ ở cấp độ cổng. Những người làm việc với các cổng nên biết một số vật lý lượng tử. Và những nhà vật lý lượng tử đó, tốt, họ vẫn đang cố gắng tìm ra sự trừu tượng tiếp theo là gì.


1
Một cấp độ sâu hơn là về quyền. Tôi có xu hướng đi tìm một cặp vợ chồng, nhưng giả sử rằng kiến ​​thức lắp ráp x86 đáng để đầu tư so với việc học MSIL cho một lập trình viên C # đang đòi hỏi quá nhiều. Là một người nghiên cứu về lắp ráp và vật lý trạng thái rắn ở uni, tôi không nghĩ rằng việc biết vật lý của thiết kế cổng đã giúp tôi rất nhiều, ngoài việc tốt nghiệp với bằng điện tử.
Muhammad Alkarouri

@MuhammadAlkarouri Tôi đã suy nghĩ theo dòng hiểu biết về sự rò rỉ hiện tại, thời gian chạy, sức đề kháng và tác động của nhiệt đối với hệ thống. Sự hiểu biết về 'tại sao' cơ bản hỗ trợ trong việc đưa ra quyết định nhiều hơn các quy tắc phân tách dấu vết tối thiểu và dung sai vận hành.

5

Vì bạn không đề cập đến C hoặc C ++ trong các ngôn ngữ bạn biết danh sách. Tôi thực sự khuyên bạn nên học tốt chúng trước cả khi nghĩ về lắp ráp. C hoặc C ++ sẽ cung cấp tất cả các khái niệm cơ bản hoàn toàn minh bạch trong các ngôn ngữ được quản lý và bạn sẽ hiểu hầu hết các khái niệm được đề cập trong trang này với một trong những ngôn ngữ quan trọng nhất mà bạn có thể sử dụng trong các dự án trong thế giới thực. Đó là một giá trị gia tăng thực sự cho kỹ năng lập trình của bạn. Xin lưu ý rằng lắp ráp được sử dụng trong các lĩnh vực rất cụ thể và nó gần như không hữu ích như C hoặc C ++.

Tôi thậm chí sẽ đi xa hơn để nói rằng bạn không nên lặn để lắp ráp trước khi hiểu làm thế nào các ngôn ngữ không được quản lý hoạt động. Nó gần như là một bài đọc bắt buộc.

Bạn nên học lắp ráp nếu bạn muốn đi xa hơn nữa. Bạn muốn biết chính xác từng cấu trúc của ngôn ngữ được tạo ra như thế nào. Nó là thông tin nhưng nó là rất nhiều mức độ phức tạp khác nhau.


5

Nếu bạn biết một ngôn ngữ tốt, bạn nên có ít nhất kiến ​​thức cơ bản về công nghệ một mức độ trừu tượng thấp hơn.

Tại sao? Khi có sự cố xảy ra, kiến ​​thức về các cơ chế cơ bản giúp dễ dàng gỡ lỗi các vấn đề lạ hơn và tự nhiên viết mã hiệu quả hơn

Sử dụng Python (/ CPython) làm ví dụ, nếu bạn bắt đầu gặp sự cố kỳ lạ hoặc hiệu suất kém, kiến ​​thức về cách gỡ lỗi mã C có thể rất hữu ích, tương tự với kiến ​​thức về phương pháp quản lý bộ nhớ đếm lại. Điều này cũng sẽ giúp bạn biết khi nào / nếu viết một cái gì đó dưới dạng phần mở rộng C, v.v.

Để trả lời câu hỏi của bạn trong trường hợp này, kiến ​​thức về lắp ráp thực sự sẽ không giúp ích cho nhà phát triển Python có kinh nghiệm (quá nhiều bước trừu tượng - mọi thứ được thực hiện trong Python sẽ dẫn đến nhiều hướng dẫn lắp ráp)

..nhưng, nếu bạn có kinh nghiệm với C, thì việc biết "xuống cấp tiếp theo" (lắp ráp) thực sự sẽ hữu ích.

Tương tự, nếu bạn đang sử dụng CoffeScript thì sẽ rất hữu ích khi biết Javascript. Nếu bạn đang sử dụng Clojure, kiến ​​thức về Java / JVM là hữu ích.

Ý tưởng này cũng hoạt động bên ngoài các ngôn ngữ lập trình - nếu bạn đang sử dụng hội, bạn nên làm quen với cách các chức năng phần cứng cơ bản. Nếu bạn là một nhà thiết kế web, bạn nên biết cách triển khai ứng dụng web. Nếu bạn là một thợ sửa xe, bạn nên có kiến ​​thức về vật lý


3

Viết chương trình c nhỏ và tháo rời đầu ra. Đó là tất cả. Tuy nhiên, hãy chuẩn bị cho một mức độ lớn hơn hoặc ít hơn của mã "dọn phòng" được thêm vào vì lợi ích của Hệ điều hành.

Hội giúp bạn hiểu những gì đang diễn ra dưới mui xe vì nó liên quan trực tiếp đến bộ nhớ, thanh ghi bộ xử lý và những thứ tương tự.

Nếu bạn thực sự muốn sử dụng kim loại trần mà không cần sự phức tạp của hệ điều hành làm phức tạp mọi thứ, hãy thử lập trình Arduino bằng ngôn ngữ lắp ráp.


3

Không có câu trả lời dứt khoát, vì các lập trình viên không phải là tất cả của một loại. Bạn có cần phải biết những gì ẩn giấu bên dưới? Nếu vậy, sau đó tìm hiểu nó. bạn chỉ muốn tìm hiểu nó, vì tò mò? Nếu vậy, sau đó tìm hiểu nó. Nếu nó sẽ không có lợi ích thiết thực cho bạn, thì tại sao phải bận tâm? Có ai cần trình độ kiến ​​thức cơ khí chỉ để lái xe không? Có một thợ máy cần trình độ kiến ​​thức của một kỹ sư, chỉ để làm việc trên một chiếc xe hơi? Đây là một sự tương tự nghiêm trọng. Một thợ máy có thể là một thợ cơ khí rất giỏi, năng suất mà không cần lặn để kỹ sư hiểu sâu về các phương tiện mà anh ta duy trì. Tương tự cho âm nhạc. Bạn có thực sự làm giảm sự phức tạp của giai điệu, hòa âm và nhịp điệu để trở thành một ca sĩ hay người chơi giỏi? Không. Một số nhạc sĩ tài năng đặc biệt không thể đọc được một bản nhạc, đừng nói cho bạn biết sự khác biệt giữa chế độ Dorian và Lydian. Nếu bạn muốn, tốt, nhưng không, bạn không cần. Nếu bạn là một nhà phát triển web, lắp ráp không có sử dụng thực tế mà tôi có thể nghĩ đến. Nếu bạn đang ở trong các hệ thống nhúng hoặc một cái gì đó thực sự đặc biệt, thì điều đó có thể là cần thiết, nhưng nếu có, bạn sẽ biết điều đó.

Đây là Joel đảm nhận những giá trị này của việc sử dụng một ngôn ngữ không cao cấp: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html


2

Trên thực tế, những gì có lẽ là tốt nhất cho bạn sẽ là một lớp không tồn tại (theo hiểu biết của tôi) ở bất cứ đâu: Đó sẽ là một lớp kết hợp một tổng quan ngắn gọn về ngôn ngữ máy / trình biên dịch và các khái niệm địa chỉ lưu trữ với một chuyến tham quan thông qua việc xây dựng trình biên dịch , tạo mã và môi trường thời gian chạy.

Vấn đề là với một ngôn ngữ cấp cao, xa rời phần cứng như C # hoặc Python, bạn không thực sự đánh giá cao thực tế rằng mỗi chuyển động bạn thực hiện biến thành hàng trăm nếu không phải là hàng ngàn hướng dẫn máy và bạn không Không có xu hướng hiểu làm thế nào một vài dòng của ngôn ngữ cấp cao có thể khiến lượng lưu trữ lớn được truy cập và sửa đổi. Nó không quá nhiều đến nỗi bạn cần biết chính xác những gì đang diễn ra "bên dưới vỏ bọc", nhưng bạn cần có sự đánh giá cao về phạm vi của những gì đang xảy ra, và một quan niệm chung về các loại sự việc xảy ra.


1

Câu trả lời của tôi cho câu hỏi này đã phát triển tương đối gần đây. Các câu trả lời hiện có bao gồm những gì tôi sẽ nói trong quá khứ. Trên thực tế, điều này vẫn được bao phủ bởi câu trả lời hàng đầu - điểm "đánh giá cao các cấu trúc trong lập trình cấp cao hơn", nhưng đó là một trường hợp đặc biệt mà tôi nghĩ là đáng nói đến ...

Theo bài đăng trên blog của Jeff Atwood , tài liệu tham khảo một nghiên cứu, hiểu bài tập là một vấn đề quan trọng trong việc hiểu lập trình. Các lập trình viên học tập hiểu rằng ký hiệu chỉ đại diện cho các bước mà máy tính tuân theo và lý do của các bước hoặc nếu không thì bị nhầm lẫn bởi các tương tự sai lệch với các phương trình toán học, v.v.

Chà, nếu bạn hiểu những điều sau đây từ trình biên dịch 6502 ...

LDA variable
CLC
ADC #1
STA variable

Đó thực sự chỉ là các bước. Sau đó, khi bạn học cách dịch nó thành một câu lệnh gán ...

variable = variable + 1;

Bạn không cần một sự tương tự sai lệch với một phương trình toán học - bạn đã có một mô hình tinh thần chính xác để ánh xạ nó tới.

EDIT - tất nhiên nếu lời giải thích bạn nhận LDA variableđược về cơ bản ACCUMULATOR = variable, đó chính xác là những gì bạn nhận được từ một số hướng dẫn và tài liệu tham khảo, bạn sẽ trở lại nơi bạn bắt đầu và nó không giúp ích gì cả.

Tôi đã học được trình biên dịch 6502 như ngôn ngữ thứ hai của mình, ngôn ngữ thứ nhất là Cơ bản hàng hóa và lúc đó tôi chưa thực sự học được nhiều thứ đó - một phần vì có quá ít thứ để học, nhưng cũng bởi vì trình biên dịch lại có vẻ thú vị hơn rất nhiều . Một phần là thời gian, một phần vì tôi là một người đam mê 14 tuổi.

Tôi không khuyên bạn nên làm những gì tôi đã làm, nhưng tôi tự hỏi nếu nghiên cứu một vài ví dụ rất đơn giản bằng ngôn ngữ trình biên dịch rất đơn giản có thể là bước đầu tiên đáng giá để học các ngôn ngữ cấp cao hơn.


0

Trừ khi bạn là một người viết trình biên dịch, hoặc cần một cái gì đó được tối ưu hóa cao (như thuật toán xử lý dữ liệu), học mã hóa lắp ráp sẽ cung cấp cho bạn không có lợi ích.

Viết và duy trì mã được viết trong lắp ráp là rất khó, do đó ngay cả khi bạn biết rất rõ ngôn ngữ trình biên dịch, bạn không nên sử dụng nó, trừ khi không có cách nào khác.

Bài viết " Tối ưu hóa cho SSE: Nghiên cứu trường hợp " cho thấy những gì có thể làm nếu bạn đi lắp ráp. Tác giả đã quản lý để tối ưu hóa thuật toán từ 100 chu kỳ / vectơ thành 17 chu kỳ / vectơ.


1
Tác giả đã không sử dụng bất kỳ hướng dẫn vectơ hoặc nội tại trong phiên bản C ++. Bạn không cần trình biên dịch để viết mã SSE.
gnasher729

@ gnasher729 Có, bạn không cần. Nhưng với lắp ráp, chương trình có thể chạy nhanh hơn nhiều. Một con người có thể thông minh hơn sau đó trình biên dịch (trong trường hợp hiếm hoi).
BЈовић

0

Viết trong lắp ráp sẽ không cung cấp cho bạn sự gia tăng tốc độ kỳ diệu do số lượng chi tiết (phân bổ đăng ký, v.v.) có thể bạn sẽ viết thuật toán tầm thường nhất từng có.

Ngoài ra, với bộ xử lý hiện đại (đọc - được thiết kế sau 70-80) sẽ không cung cấp cho bạn đủ số lượng chi tiết để biết điều gì đang xảy ra (nghĩa là - trên hầu hết các bộ xử lý). PU hiện đại (CPU và GPU) khá phức tạp theo hướng dẫn lập lịch. Biết các kiến ​​thức cơ bản về lắp ráp (hoặc giả) sẽ cho phép hiểu các sách / khóa học về kiến ​​trúc máy tính sẽ cung cấp thêm kiến ​​thức (bộ nhớ cache, thực hiện không theo thứ tự, MMU, v.v.). Thông thường, bạn không cần biết ISA phức tạp để hiểu chúng (MIPS 5 khá phổ biến IIRC).

Tại sao hiểu bộ xử lý? Nó có thể giúp bạn hiểu nhiều hơn những gì đang diễn ra. Giả sử bạn viết phép nhân ma trận theo cách ngây thơ:

for i from 0 to N
    for j from 0 to N
        for k from 0 to N
            A[i][j] += B[i][k] + C[k][j]

Nó có thể là 'đủ tốt' cho mục đích của bạn (nếu là ma trận 4 x 4 thì nó có thể được biên dịch thành các hướng dẫn vectơ). Tuy nhiên, có những chương trình khá quan trọng khi bạn biên dịch các mảng lớn - làm thế nào để tối ưu hóa chúng? Nếu bạn viết mã trong hội đồng, bạn có thể có một vài% cải thiện (trừ khi bạn sẽ làm như hầu hết mọi người làm - cũng theo cách ngây thơ, sử dụng không đúng các thanh ghi, tải / lưu trữ vào bộ nhớ liên tục và thực tế là có chương trình chậm hơn bằng ngôn ngữ HL) .

Tuy nhiên, bạn có thể đảo ngược các dòng tho và đạt được hiệu suất một cách kỳ diệu (tại sao? Tôi để nó là 'bài tập về nhà') - IIRC tùy thuộc vào các yếu tố khác nhau cho ma trận lớn, nó có thể thậm chí là 10 lần.

for i from 0 to N
    for k from 0 to N
        for j from 0 to N
            A[i][j] += B[i][k] + C[k][j]

Điều đó nói rằng - đang làm việc trên các trình biên dịch có thể làm điều đó ( than chì cho gcc và Polly cho bất cứ điều gì sử dụng LLVM). Họ thậm chí có khả năng biến nó thành (xin lỗi - tôi đang viết chặn khỏi bộ nhớ):

for i from 0 to N
    for K from 0 to N/n
        for J from 0 to N/n
            for kk from 0 to n
                for jj from 0 to n
                    k = K*n + kk
                    j = J*n + jj
                    A[i][j] += B[i][k] + C[k][j]

Tóm lại - việc biết những điều cơ bản của một hội đồng cho phép bạn đào sâu vào nhiều 'chi tiết' khác nhau từ thiết kế bộ xử lý cho phép bạn viết các chương trình nhanh hơn. Có thể là tốt để biết sự khác biệt giữa các kiến ​​trúc RISC / CISC hoặc VLIW / vector / SIMD / .... Tuy nhiên tôi sẽ không bắt đầu với x86 vì chúng có xu hướng khá phức tạp (có thể cả ARM nữa) - biết đăng ký là gì, vv là IMHO đủ để bắt đầu.


Tôi thấy thú vị khi bạn cung cấp một số mẫu mã, nhưng không có
Robert Harvey

-1

Thông thường nó RẤT quan trọng cho mục đích gỡ lỗi. Bạn làm gì khi hệ thống bị hỏng giữa một lệnh và lỗi không có ý nghĩa? Đó không phải là vấn đề với các ngôn ngữ .NET, miễn là bạn chỉ sử dụng mã an toàn - hệ thống hầu như sẽ luôn bảo vệ bạn khỏi những gì đang diễn ra dưới mui xe.


-2

Tóm lại tôi nghĩ câu trả lời là bởi vì bạn có thể làm nhiều hơn nếu bạn học lắp ráp. Học lắp ráp cho phép truy cập vào các lĩnh vực lập trình thiết bị nhúng, thâm nhập và phá vỡ bảo mật, kỹ thuật đảo ngược và lập trình hệ thống rất khó để làm việc nếu bạn không biết trình biên dịch.

Đối với việc học nó để cải thiện hiệu suất chương trình, điều này rất đáng nghi ngờ trong lập trình ứng dụng. Hầu hết thời gian có rất nhiều thứ cần tập trung vào trước khi đạt mức tối ưu hóa này như tối ưu hóa quyền truy cập i / o của bạn trên cả đĩa và mạng, tối ưu hóa cách bạn xây dựng GUI, chọn thuật toán phù hợp, tối đa hóa tất cả các lõi của bạn , chạy bằng tiền phần cứng tốt nhất có thể mua và chuyển từ ngôn ngữ được dịch sang ngôn ngữ được biên dịch. Trừ khi bạn đang tạo phần mềm cho người dùng cuối khác, phần cứng rẻ so với mức lương hàng giờ của lập trình viên, đặc biệt là có sẵn trên đám mây.

Ngoài ra, bạn phải cân nhắc tốc độ thực thi chương trình tăng lên với khả năng đọc mã của bạn sau khi bạn bị xe buýt đâm, thoát hoặc quay lại cơ sở mã để thay đổi một năm sau khi bạn viết phiên bản cuối cùng.


-3

Tôi muốn giới thiệu các thuật toán học tập: sắp xếp, danh sách liên kết, cây nhị phân, băm, v.v.

Ngoài ra, hãy tìm hiểu cấu trúc và diễn giải các nhóm chương trình máy tính.csail.mit.edu/mac/groupes/6.001/abelson-sussman-lectures khóa học video này sẽ dạy cho bạn mọi thứ bạn cần biết, bao gồm cả thuật toán (cách làm mọi thứ dựa trên một vài lệnh nguyên thủy, một lệnh thô sơ và một số khiêu khích lắp ráp).

Cuối cùng, nếu bạn phải học trình biên dịch, hãy học một trình dễ dàng như ARM (cũng được sử dụng trong các thiết bị nhiều hơn khoảng 4 lần so với x86).


-8

Vâng, câu trả lời là chỉ đơn giản vì ngôn ngữ bạn đang sử dụng phải được giải thích hoặc biên dịch thành trình biên dịch cuối cùng. Bất kể ngôn ngữ hay máy móc.

Thiết kế của các ngôn ngữ bắt nguồn từ cách CPU hoạt động. Thêm về các chương trình cấp thấp, ít hơn về các chương trình cấp cao.

Tôi sẽ kết thúc bằng cách nói rằng không chỉ bạn cần biết ít trình biên dịch mà cả kiến ​​trúc CPU, mà bạn học bằng cách học trình biên dịch.

Một số ví dụ: Có nhiều lập trình viên java không hiểu tại sao điều này không hoạt động và thậm chí còn ít biết điều gì sẽ xảy ra khi bạn chạy nó.

String a = "X";
String b = "X";
if(a==b)  
    return true;

Nếu bạn biết một trình biên dịch mã nhỏ, bạn sẽ luôn biết rằng nó không giống với nội dung của một vị trí bộ nhớ so với số trong biến con trỏ "trỏ" đến vị trí đó.

Thậm chí tệ hơn, ngay cả trong các cuốn sách được xuất bản, bạn sẽ đọc một cái gì đó như trong các nguyên thủy JAVA được truyền qua giá trị và các đối tượng bằng tham chiếu, điều này hoàn toàn không chính xác. Tất cả các đối số trong Java được truyền theo giá trị và Java KHÔNG thể truyền đối tượng cho các hàm, chỉ các con trỏ, được truyền theo giá trị.

Nếu bây giờ bạn lắp ráp rõ ràng những gì đang diễn ra, nếu không nó quá phức tạp để giải thích rằng hầu hết các tác giả chỉ cho bạn một lời nói dối ngoan đạo.

Tất nhiên, sự phân nhánh của những điều này là tinh tế nhưng có thể khiến bạn gặp rắc rối thực sự sau này. Nếu bạn biết trình biên dịch thì đó không phải là vấn đề, nếu không, bạn sẽ ở trong một đêm dài để gỡ lỗi.


5
Đoạn đầu tiên của bạn hoàn toàn không chính xác: các ngôn ngữ không được biên dịch thành ASM, chúng được biên dịch thành Mã máy. Các trình thông dịch không biên dịch thành ASM, họ giải thích mã hoặc mã byte và gọi các hàm hoặc phương thức trên mã máy được biên dịch trước.

6
Bao giờ điều duy nhất bạn tuyên bố về Java là không chính xác. Bắt đầu với String a = "X"; String b = "X"; if( a==b) return true;cái nào trong thực tế == truevì cái gì đó được gọi là String interningtrình biên dịch. Tất cả các câu lệnh Java khác đều sai. Java không có con trỏ, nó có các tham chiếu không giống nhau. Và không ai trong số đó có bất cứ điều gì liên quan đến lắp ráp trong bất kỳ thời trang nào. Java chuyển các nguyên thủy theo giá trị cũng như các tham chiếu theo giá trị. Java không có con trỏ nên nó không thể vượt qua chúng bằng bất cứ thứ gì. Một lần nữa tất cả không liên quan để biết ASM.

Tôi luôn nghĩ các ngôn ngữ cấp cao hơn được biên dịch thành đối tượng (mã máy) hoặc mã giả, và không thành ASM.
Frank R.

@FrankComputer đúng, nhưng mã máy byte khá nhiều ánh xạ 1: 1 sang hướng dẫn lắp ráp, do đó bạn có thể dễ dàng dịch giữa một đối tượng mã và ASM (dịch ngược hoặc lắp ráp)
dbr

2
@FrankComputer lần trước tôi đã xem gcc đã biên dịch C / C ++ / fortran / java / ada / etc thành mã byte nội bộ và mã byte nội bộ cho trình biên dịch. Sau đó, nó gửi mã trình biên dịch mã này đến một trình biên dịch mã để chuyển đổi nó thành mã máy.
ctrl-alt-delor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.