ฉันพบหนังสือที่น่าทึ่งเล่มนี้ทางออนไลน์ xchg rax, rax โดย xorpd เป็นการรวบรวมปริศนาประกอบ หนังสือเล่มนี้มีตัวอย่างประกอบขนาดสั้น 0x40 โดยไม่มีข้อความ
ฉันเพิ่งเริ่มอ่านมันและมันน่าทึ่งมาก ฉันจะอัปเดตโพสต์บล็อกนี้พร้อมคำอธิบายตัวอย่างที่ฉันสำรวจ
xchg rax,rax — 0x00 คำอธิบาย
คำแนะนำ: เป็นตัวอย่างข้อมูลที่ 0
ตัวอย่างเพียงแสดงวิธีต่างๆ ในการตั้งค่ารีจิสเตอร์เป็น 0 โดยตั้งค่า eax, ebx, ecx, edx, esi, edi และ ebp เป็น 0 ในลำดับเดียวกัน
xchg rax,rax — คำอธิบาย 0x01
ฟีโบนัชชี
xchg rax,rax — คำอธิบาย 0x02
ตั้งค่า rax เป็น 0 หากค่าเริ่มต้นเป็น 0 มิฉะนั้นจะตั้งค่าเป็น 1 เสมอ
xchg rax,rax — คำอธิบาย 0x03
จริงๆ แล้วโค้ดนั้นเป็นวิธีที่ชาญฉลาดในการทำ rax = min(rax, rdx)
sub rdx, rax ; rdx = rdx - rax; CF set if rdx < rax
sbb rcx, rcx ; rcx = all 1 bits if CF was set, 0 otherwise
and rcx, rdx ; rcx = rdx - rax if CF was set, 0 otherwise
add rax, rcx ; rax = rax + (rdx - rax) = rdx if CF was set, unchanged otherwise
เวอร์ชันการแตกแขนงที่อ่านได้มากขึ้นคือ:
cmp rdx, rax
jnc done ; if rdx - rax produced no carry, rax is smaller or equal
mov rax, rdx ; otherwise rdx is the smaller one
done:
ยังคงใช้ CF สำหรับการตรวจสอบโอเวอร์โฟลว์เท่านั้น
จากคำตอบของ Jester ที่นี่
xchg rax,rax — คำอธิบาย 0x04
0x20 ในไบนารี่คือ 00100000
ดังนั้นการ xor ตัวเลขด้วย 0x20 จะพลิกบิตที่สำคัญที่สุดอันดับที่ 5 ทีนี้ หากเราเห็นการแสดงอักขระ ASCII ในรูปแบบไบนารี่ ก็มีสิ่งที่น่าสนใจที่ควรทราบ
A = 0100 0001 a = 0110 0001 B = 0100 0010 b = 0110 0010
ที่นั่นเราเห็น การพลิกบิตที่ห้าจะเป็นการพลิกตัวพิมพ์ (ล่าง/บน) ของตัวอักษร