Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Debugging 装配保险箱和钥匙-为什么它赢了';不行?_Debugging_Assembly_Reverse Engineering_X86 16_Corewars - Fatal编程技术网

Debugging 装配保险箱和钥匙-为什么它赢了';不行?

Debugging 装配保险箱和钥匙-为什么它赢了';不行?,debugging,assembly,reverse-engineering,x86-16,corewars,Debugging,Assembly,Reverse Engineering,X86 16,Corewars,因此,我们在组装中遇到了类似保险柜的挑战,您需要创建保险柜和钥匙,以打破它们并结束无限循环。 下面是一个保险箱的示例: 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,

因此,我们在组装中遇到了类似保险柜的挑战,您需要创建保险柜和钥匙,以打破它们并结束无限循环。 下面是一个保险箱的示例:

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
中的值来自第一条
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 iif(同样,当将乘法看作左移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 
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 

如果有钥匙打开保险柜,则钥匙必须大于或等于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 (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 
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。

用作
循环
指令计数器的
dx
中的值来自第一条
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 iif(同样,当将乘法看作左移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 
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 

如果有钥匙打开保险柜,则钥匙必须大于或等于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 (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 
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。

您的“钥匙”永远不会退出。这不是问题吗?它应该只需要运行一次,就可以永远解锁“安全”循环。除非你在一个多任务操作系统下运行多个进程,否则无限循环是不好的。你的“安全”太复杂了,我无法在脑海中模拟。在调试器中单步执行时,是否看到它从
[5768h]
加载
10
?如果是这样,那么它最终不是以ax==350而结束吗?“不起作用”的细节不够详细。我的密钥应该在无限循环中运行。它运行在codeguru的程序中,密钥应该是赢的,这意味着它应该打破保险箱的无限循环。然而,结果总是平局。意味着钥匙不起作用,你的“钥匙”永远不存在。这不是问题吗?它应该只需要运行一次,就可以永远解锁“安全”循环。除非你在一个多任务操作系统下运行多个进程,否则无限循环是不好的。你的“安全”太复杂了,我无法在脑海中模拟。在调试器中单步执行时,是否看到它从
[5768h]
加载
10
?如果是这样,那么它最终不是以