[英]Assembly safes and keys- why it won't work?
所以我們在組裝中遇到了這樣的保險箱挑戰,你需要創建保險箱和鑰匙來打破它們並結束無限循環。 下面是一個保險箱的例子:
loopy:
mov ax, [1900]
cmp ax,1234
jne loopy
和一把鑰匙:
loopy2:
mov ax, 1234
mov [1900],ax
jmp loopy2
所以我有一個保險箱和一把鑰匙,我不明白為什么它不起作用:
這是我的保險箱:
org 100h
mySafe:
mov dx,5
mov ax, [5768h]
mov bx,7
mov word [180h],2
mul word [180h]
mov [180h],bx
push ax
dec bx
mov cx,dx
mov ax,dx
loopy1:
add bx,ax
loop loopy1
dec bx
pop ax
add ax,bx
mul word [180h]
cmp ax,350
jne mySafe
這是我的鑰匙:
org 100h
loopy:
mov word [5768h],10
jmp loopy
ret
打破循環的正確答案應該是 10,當我放入保險箱時它會起作用,但不知何故它不起作用,我不知道為什么..(nasm 需要“詞”)
dx
用作loop
指令計數器的值來自第一條mul
指令。
這個乘法只是將密鑰加倍,所以dx
是 0 或 1(一個簡單的方法是將乘法視為左移 1 或記住兩個 n 位數字之和至多有n +1位)
如果dx
為零,則整個loopy1
塊什么都不做(因為dx
也設置了ax
)並且保險箱末尾的ax
中的值是 7*(5 +2k) 其中k是鍵(請參閱下面的注釋代碼)。
然后很容易看出 350 = 7*(5+2k) => 2k = 45 沒有解。 因此,沒有dx
為零的鑰匙可以解鎖保險箱。
如果鍵的值小於 32768,則鍵的dx
0(同樣,將乘法視為左移 1 時很容易看出這一點)。
推論:10 不能是一個解決方案。
safe:
mov dx,5
mov ax, [k] ;ax = k (key)
mov bx,7
mov word [aux],2
mul word [aux] ;dx = 0 ax = 2k
mov [aux],bx ;aux = 7
push ax ;ax = 2k
dec bx ;bx = 6
dec bx ;bx = 5
pop ax ;ax = 2k
add ax,bx ;ax = 5 + 2k
mul word [aux] ;ax = 7*(5 +2k)
cmp ax,350
ret
如果有解鎖保險箱的鑰匙,那么它必須大於或等於 32768,以便在第一次乘法后dx
為 1。 在這種情況下,保險箱末端ax
中的值可以寫為 7*(6 + (2k & 0xffff)) => k & 0x7fff = 22。
加上本節開頭所述的條件, k的最終值為 32768 + 22 = 32790 或 0x8016(十六進制) 。 我在操縱方程和形成結果方面已經跳過了很多合乎邏輯的步驟,但是,再次將2k
視為一種轉變可能有助於將它們可視化。
推論:由於涉及代數結構,這是唯一的解決方案。
safe:
mov dx,5
mov ax, [k] ;ax = k
mov bx,7
mov word [aux],2
mul word [aux] ;dx:ax = 2k
mov [aux],bx ;[aux] = 7
push ax ;dx = 1 ax = 2k & 0xffff
dec bx ;bx = 6
mov cx,dx ;cx = 1
mov ax,dx ;ax = 1
loopy1:
add bx,ax ;bx = 6 + 1
dec cx
jnz loopy1
dec bx ;bx = 6
pop ax ;ax = 2k & 0xffff
add ax,bx ;ax = 6 + (2k & 0xffff)
mul word [aux] ;ax = 7*(6 + (2k & 0xffff))
cmp ax,350
ret
考慮到您在第一次乘法之前有一個mov dx, 5
,您(或保險箱的作者)是否忘記了mul
影響dx
?
如果你將第一個mul
包裹在push dx / pop dx
(或者只是移動mov dx, 5
在它之后),你會得到,在保險箱的最后, ax
的值等於 7*(30 +2k) 這意味着k = 10確實。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.