ฉันควรพยายามฝึกปัญหาในการชุมนุมหรือไม่? [ปิด]


9

ฉันกำลังดูปัญหาโครงการออยเลอร์ 48 :

ชุดนี้ 1 1 + 2 2 + 3 3 + ... + 10 10 = 10405071317

ค้นหาหลักสิบสุดท้ายของซีรีส์ 1 1 + 2 2 + 3 3 + ... + 1000 1000

ใน Python ฉันสามารถทำได้ด้วยบรรทัดเดียว:

sum((x**x for x in xrange(1,1001))

แต่การประกอบของสิ่งนี้จะเท่ากับ 100 บรรทัดและเป็นความท้าทายที่แท้จริง

ฉันควรทำจิ๊กซอว์เหล่านี้เพื่อประกอบการเรียนรู้ในการเขียนโปรแกรมระดับต่ำและเข้าใจว่าคอมพิวเตอร์ใช้งานได้จริงอย่างไร?


2
หากคุณไม่ทราบว่าหน่วยความจำทำงานอย่างไรคุณจะได้รับการจัดการหัวข้อเช่นพอยน์เตอร์ได้อย่างไร หากคุณไม่เข้าใจว่าคอมพิวเตอร์และระบบปฏิบัติการทำงานอย่างไรคุณจะตั้งโปรแกรมแอปพลิเคชันได้อย่างไร
Ramhound

ฉันสามารถสร้างบทคัดย่อจำนวนมาก Ramhound นั่นเป็นสาเหตุที่ฉันถามคุณในเรื่องนี้ ฉันอาจไม่ได้รับพอยน์เตอร์ที่เต็มรูปแบบที่ยังคงสามารถทำอะไรบางอย่างในพอยน์เตอร์เช่นการสลับซึ่งทำให้รู้สึกตรรกะเมื่อคุณคิดพอยน์เตอร์เก็บตำแหน่งหน่วยความจำของประเภทข้อมูลอื่น ๆ อีก Ramamound ตั้งแต่คุณแนะนำว่า หัวข้อที่ฉันควรอ่าน ภาษาแอสเซมบลีและ COA เล็กน้อยจะดีไหม
Nishant

หากคุณไม่ได้รับคำชี้แนะอย่างเต็มที่คุณจะพบว่าการเสียเปรียบครั้งใหญ่ในบางสถานที่
David Thornley

3
ไพ ธ อนสายของคุณคำนวณ x ^ 2 สำหรับ x ใน 1..1000 (แทนที่จะเป็น x ^ x สำหรับ x ใน 1..1000) หรือไพ ธ อนนั้นวิเศษยิ่งกว่าที่ฉันคิด :)
Ingo

ฟังก์ชัน "ยกระดับพลังของ" *ใน Python หรือไม่

คำตอบ:


1

นอกเหนือจากการเรียนรู้การชุมนุมฉันเชื่อว่าการเรียนรู้วิธีการรวบรวมภาษาระดับต่ำเช่น C มีค่าสูง ดังนั้นคำตอบของฉันคือใช่ แต่แล้วอีกครั้งฉันอาจจะลำเอียงเพราะฉันสนุกกับการเขียนโปรแกรมระดับต่ำ

ตัวอย่างเช่นเพียงแค่เข้าใจว่าคอมไพล์คำสั่งง่าย ๆ ฟังก์ชั่นดังต่อไปนี้

int func(int val)
{
  int num = val * 5;
  return num;
}

... กลายเป็น (บิตที่น่าสนใจอย่างน้อย):

movl    %edi, -20(%rbp)
movl    -20(%rbp), %edx
movl    %edx, %eax
sall    $2, %eax
addl    %edx, %eax

รหัสนี้ใช้อาร์กิวเมนต์จากสแต็ค (val, พารามิเตอร์ถึง func) เลื่อนไปทางซ้าย 2 ตำแหน่ง (คูณด้วย 2 ^ 2 หรือ 4) จากนั้นเพิ่มค่าดั้งเดิมลงในผลลัพธ์ ผลลัพธ์ที่ได้คือการคูณด้วย 5 ตัวอย่างเช่นนี้แสดงจำนวนของสิ่งที่ต้องระวังเช่นการเพิ่มประสิทธิภาพของคอมไพเลอร์ แทนที่จะเรียกคำสั่งให้คูณโดยตรง 5 มันเลื่อนตำแหน่งสองแห่งเพื่อคูณด้วย 4 แล้วเพิ่มค่าเดิม ฉันพบตัวอย่างเช่นนี้เพื่อปรับปรุงความเข้าใจในสิ่งต่าง ๆ ในระดับต่ำลงอย่างมาก

สร้างเอาต์พุตแอสเซมเบลอร์จาก gcc ด้วย-Sตัวเลือก อย่างไรก็ตามโปรดทราบว่าผลลัพธ์จะแตกต่างกันตามคอมไพเลอร์และระดับการเพิ่มประสิทธิภาพ

อย่างไรก็ตามผมไม่คิดว่าการเป็นโปรแกรมเมอร์ภาษาประกอบเป็นเช่นเดียวกับการทำความเข้าใจการชุมนุม อีกครั้งฉันรู้สึกว่าการเขียนโปรแกรมในภาษาเช่น C และรู้วิธีที่จะนำไปใส่ในรหัสเครื่องเป็นการฝึกฝนที่มีค่า


11

อาจไม่จำเป็นที่จะสามารถเขียนแอสเซมเบลอร์ได้ (ส่วนใหญ่จะเป็นรายละเอียด sis ของการเริ่มต้นและการเรียกแบบแผนสำหรับระบบของคุณ)

เป็นสิ่งที่ควรค่าแก่การทำความเข้าใจในกรณีที่คุณพยายามแก้ไขข้อบกพร่องบางอย่างโดยไม่มีแหล่งที่มา

แต่มันก็คุ้มค่าที่จะเข้าใจเครื่องอย่างน้อยที่สุดในระดับ 'C' และพอยน์เตอร์ (โดยพื้นฐานแล้วเป็นแอสเซมเบลอร์ระดับสูง) เพื่อให้คุณรู้ว่าทำไมการต่อสตริงเป็นล้าน ๆ ครั้งในลูปนั้นไม่ดี


ที่จริงแล้วการใช้งานที่ค่อนข้างฉลาดบางอย่างสามารถทำให้for i in range(1000000): s = s + '.'ไม่มี (แย่กว่า) ที่แย่กว่า "ปรับ" รุ่นที่ฉันใช้sซ้ำ ในทำนองเดียวกันการพัฒนาอื่น ๆ หลายทำให้โมฆะสิ่งที่เป็นสมมติฐานที่สมเหตุสมผลกับความรู้ C และสมมติว่าการดำเนินการไร้เดียงสา แต่โดยทั่วไปแล้วมันมีประโยชน์มากกว่าที่เป็นอันตราย เพียงจำไว้ว่าการใช้งานภาษาบางครั้งฉลาดกว่าคุณ;)

2
@delnan - ฉันแค่ต้องการตัวอย่างสั้น ๆ ว่ามีบางสิ่งที่ดูไร้เดียงสาใน Java / C # อาจมีราคาแพงมากบนซิลิคอน ฉันเจอคนจำนวนมากโดยเฉพาะที่คิดว่าการจัดสรรหน่วยความจำขนาดใหญ่และการคัดลอกนั้นเป็นสิ่งที่เกิดขึ้นทันที
Martin Beckett

ฉันเกลียดที่จะเชื่อว่า delnan :-)
Nishant

5

คำถามที่ดี. Learning Assemblyเป็นสิ่งที่ดีและคุ้มค่ากับความพยายาม

  1. ความเข้าใจในระดับต่ำดังกล่าวจะเป็นประโยชน์ในการพัฒนาซอฟต์แวร์ฝังตัว
  2. การรีแฟคเตอร์ในระดับต่ำ
  3. มันจะช่วยคุณในการใช้ดีบักเกอร์อย่างมีประสิทธิภาพ
  4. ให้ความเข้าใจในการถอดรหัสเพื่อช่วยในสิ่งต่าง ๆ เช่นถ้ำรหัส

2
ฉันต้องค้นหา codecaves ฉันใช้สิ่งเหล่านี้มาก แต่เราเรียกพวกเขาว่า "Detours" ตอนนี้ research.microsoft.com/en-us/projects/detours
ProdigySim

1

ใช่และไม่.

แม้ว่ามันจะเป็นความจริงที่ว่ามันจะช่วยให้คุณเข้าใจดียิ่งขึ้นว่าโค้ดของคุณกำลังทำอะไรและทำไมบางสิ่งเป็นเพียงความคิดที่ไม่ดีคุณต้องคิดเกี่ยวกับความพยายาม

การเรียนรู้แอสเซมเบลอร์ไม่ใช่โครงการวันหยุดสุดสัปดาห์คุณจะต้องใช้เวลามากและคุณต้องคิดว่าคราวนี้น่าจะดีกว่านี้หรือไม่

หากคุณไม่ได้ปรับรหัสให้เหมาะสมคุณอาจจะไม่เคยเห็นประโยชน์เท่าที่คุณพยายาม


1

ฉันทำแอสเซมเบลอร์มากตอนที่ฉันยังเด็กและฉันไม่คิดว่ามันจะช่วยให้เข้าใจอะไรนอกเหนือจากแอสเซมเบลอร์ ถ้าคุณดูที่แอสเซมเบลอร์สมัยใหม่มันเป็นภาษาแมโครทั้งหมดอยู่แล้ว ฉันมักจะเกลียดการอุปมาอุปมัย แต่ต่อไป: รู้ว่าเครื่องยนต์ของรถยนต์ทำงานอย่างไรทำให้คุณเป็นคนขับที่ดีกว่า?


การรู้ว่าเครื่องยนต์ของรถยนต์ทำงานอย่างไรทำให้คุณเป็นคนขับที่ดีกว่า? ไม่ แต่มันทำให้คุณเป็นเจ้าของรถยนต์ที่ดีขึ้นเพราะถ้าเครื่องยนต์พังคุณสามารถแก้ไขได้
คาเมรอนมาร์ติน

เห็นด้วย แต่ก็ไม่ได้ทำให้คุณเป็นคนขับที่ดีกว่าซึ่งก็คือการเปรียบเทียบที่ฉันใช้ ด้วยการซ่อมเครื่องยนต์ด้วยตัวคุณเองคุณจะไม่สนับสนุนเศรษฐกิจที่กว้างขึ้นด้วยการใช้กลไกกลไก ... อะนาล็อกมาพร้อมกับข้อ จำกัด โดยทั่วไปฉันไม่เคยกีดกันใครบางคนจากการมองหาเรียนรู้บางอย่างหากพวกเขาสนใจ แต่ฉันคิดว่าคุณต้องลงลึกลงไปในโพรงกระต่ายเพื่อที่จะสามารถนำไปใช้ประโยชน์กับภาษาระดับสูงได้ สำหรับการเริ่มต้นคุณต้องเข้าใจการเพิ่มประสิทธิภาพการคอมไพล์ที่ใช้โดยภาษาเฉพาะถ้าคอมไพล์หรือการแปลหรือการกระวนกระวายใจ มันเป็นพื้นที่ขนาดใหญ่
เอียน

1

วิธีที่ฉันทำงานทำความเข้าใจเกี่ยวกับแอสเซมเบลอร์คือการเขียนโปรแกรมในภาษาระดับสูงกว่าจากนั้นแทนที่ชิ้นส่วนด้วยส่วนที่เทียบเท่ากับโค้ดที่ประกอบหน้าที่ (อย่างน้อยหวังว่า) ซึ่งหมายความว่าฉันจะใช้ HLL สำหรับสิ่งที่พวกเขาดีสำหรับการจัดระเบียบและการแก้ปัญหาระดับสูง - และฉันใช้ asm สำหรับการต่อสู้กับโลหะ

(เมื่อฉันพูดถึงโปรแกรมโฮสต์ที่เขียนด้วย HLL ฉันหมายถึง C หรือ ObjC เมื่อฉันพยายามเรียนรู้ x86_64 asm และ BASIC เมื่อฉันทำงานกับ Z80, 6502 และ 6809 asm)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.