x86 แอสเซมบลีที่เกิดขึ้นของอักขระ

  • บทนำ
  • ปัญหา
  • สารละลาย
  • คำอธิบาย

บทนำ

แบบฝึกหัดการประกอบขนาดเล็กด้านล่างนี้ใช้สำหรับสถาปัตยกรรม x86 (Intel และ AMD 32 บิต) และใช้ไวยากรณ์ NASM ซึ่งเป็นแอสเซมเบลอร์ให้ใช้งานฟรีและ

ที่สามารถใช้บนแพลตฟอร์มต่าง ๆ เช่น Windows หรือ Linux

โปรดทราบว่าฟังก์ชั่นภายนอกที่ใช้มาจากไลบรารี C มาตรฐาน

ปัญหา

ลองนึกภาพชุดอักขระ (ซึ่งไม่จำเป็นต้องลงท้ายด้วย 0) มันมีขนาดของมันและเราอยากจะทดสอบการมีอยู่ของตัวละคร

ในอาเรย์นี้ จุดมุ่งหมายจะเขียนฟังก์ชั่นที่ใช้เป็นอาเรย์ของตัวละครขนาดและตัวละคร หากตัวละครนี้มีอยู่ใน

อาร์เรย์จะส่งคืนค่าที่ไม่ใช่ศูนย์มิฉะนั้นจะส่งกลับค่าศูนย์

นี่คือสิ่งที่ให้ฟังก์ชั่นนี้ใน C:

 / ฟังก์ชั่น int is_in_array (อาร์เรย์ถ่าน *, ขนาด int, ถ่านค) // การใช้งาน: char tab [] = {'n', 'e', ​​'u', 'e'}; is_in_array (แท็บ, ขนาดของ (แท็บ), 'u'); // คืนค่าอื่นที่ไม่ใช่ 0 is_in_array (แท็บ, ขนาดของ (แท็บ), 'a'); // คืนค่า 0 เพียงใส่รหัสของคุณใน: extern printf section .data array db 'dadedidadedavivoufufifamasibifisaz' ใช่ db 'oui', 10, 0 no db 'ไม่ใช่', 10, 0 ส่วน. ข้อความหลักสากล is_in_array: ใส่รหัสของคุณ มีหลัก: push ebp mov ebp, esp; ทดสอบว่า m อยู่ในอาร์เรย์ push dword 'm' หรือไม่, ความยาวของอาร์เรย์ (ที่นี่ 34) push dword 34, ที่อยู่สตริงใน eax push array โทร is_in_array พร้อมที่อยู่ของอาร์เรย์; ขนาดและค่าที่คุณกำลังค้นหาการเรียก is_in_array ทดสอบ eax, eax jnz is_there; ถ้า eax! = 0 แสดงใช่ผลักไม่ใช่, จากนั้นแสดงไม่มี jmp screendisplay; screendisplay ของสตริงด้วย printf is_there ผลักใช่ screendisplay: printf mov eax ลาออก 

แน่นอนว่ามันจะไม่เพียงพอ .....

สารละลาย

 is_in_array:; ดึงที่อยู่ของอาร์เรย์ (พารามิเตอร์แรก) ใน edi mov edi, [esp + 4]; ดึงขนาดของอาร์เรย์ (พารามิเตอร์ที่สอง) ใน ecx mov ecx, [esp + 8] ดึงอักขระเพื่อค้นหา (พารามิเตอร์ที่สาม) ใน eax mov eax, [esp + 12]; ค้นหาอักขระ repne scasb; หาก flag ZERO (ZF) มีค่า 1 หมายถึงหมายถึงพบอักขระในอีกกรณีหนึ่งไม่พบเพียงเพิ่ม ค่าของ ZF ใน eax mov eax, 0; ถ้า ZF = 1 ดังนั้น al = 1 (al เป็น 8 บิตที่มีนัยสำคัญน้อยที่สุดของ eax) setz al ret 

คำอธิบาย

 ZF = 0 ecx = length eax = character edi = array // The loop ที่กำหนด "repne scasb" ในขณะที่ ecx! = 0 ET ZF = 0 ทำถ้า al == [edi] ZF = 1 FinSi ecx = ecx - 1 edi = edi + 1 EndWhile eax = 0 // เงื่อนไขที่กำหนด "setz" Si ZF = 1 Alors eax = 1 EndIf 
บทความก่อนหน้านี้ บทความถัดไป

เคล็ดลับยอดนิยม