簡體   English   中英

組裝保險箱和鑰匙 - 為什么它不起作用?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM