初步理解了汇编,反了一下strcpy

时间:2023-02-03 09:58:24

1、堆栈相关指令
任意时刻,SS:SP指向栈顶元素
push ax
由以下两步完成
(1) SP=SP-2,SS:SP 指向当前栈顶前面的单元,以当前栈顶前面的单元为新的栈顶
(2) 将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时执行新栈顶

pop ax
(1) 将SS:SP指向的内存单元处的数据送入ax中
(2) SP=SP+2,SS:SP 指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶


SUB OPRD1,OPRD2 
OPRD1-OPRD2  结果放在OPRD1寄存器中

 ADD OPRD1,OPRD2
OPRD1+OPRD2  结果放在OPRD1寄存器中

 CALL OPRD
相当于
push 当前指令语句的下一条地址
jmp OPRD

ret
相当于
pop  把返回的地址弹出来
jmp 上面弹出的地址

2、数据传送指令
 MOV OPRD1,OPRD2
将OPRD1寄存器的内容设置为OPRD2中的值

XOR OPRD1,OPRD2 
实现两个操作数按位‘异或’运算,结果送至 OPRD1操作数中.

常见
xor eax,eax 
功能等价于mov eax,0
xor eax,eax  机器码 33 C0
mov eax,0     机器码 B8 00 00 00 00

对比了下机器码,相同的功能xor eax,eax 少了3个字节
所以选用第一种方法清理寄存器,程序员都很精^―^


 LEA OPRD1,OPRD2 
 将源操作数给出的有效地址传送到指定的的寄存器中.


void CMainTestDlg::OnBnClickedButton1()
{
const char *p = "12345678";
char szBuff[10];
strcpy(szBuff,p);
OutputDebugString(szBuff);
}

strcpy编译后产生的反汇编代码

ds:[4025F8]  为“12345678”常量字符串的首地址
ss:[esp]   此时执向了szBuff的首地址
随着eax的增加,直到cl为0才结束循环,执行jnz之后代码

0040115E   .  33C0                             xor eax,eax
00401160   >  8A88 F8254000           mov cl,byte ptr ds:[eax+4025F8]
00401166   .  880C04                         mov byte ptr ss:[esp+eax],cl
00401169   .  40                                 inc eax
0040116A   .  84C9                             test cl,cl
0040116C   .^ 75 F2                           jnz short MainTest.00401160




7 个解决方案

#1


初步理解了汇编,反了一下strcpy
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
初步理解了汇编,反了一下strcpy多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! 初步理解了汇编,反了一下strcpy

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

#2


引用 1 楼 zhao4zhong1 的回复:
初步理解了汇编,反了一下strcpy
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
初步理解了汇编,反了一下strcpy多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! 初步理解了汇编,反了一下strcpy

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。


求教一个不相关的问题,一段C代码,我想看看变量的值是如何变化的,调什么窗口?

#3


      Visual FoxPro 9.0 SP2  
Watch Window (Visual FoxPro)  
See Also  
 Language Filter: All Language Filter: Multiple Language Filter: Visual Basic Language Filter: C# Language Filter: C++ Language Filter: J# Language Filter: JScript  
 Visual Basic (Declaration) 
 Visual Basic (Usage) 
 C# 
 C++ 
 J# 
 JScript 

Makes it possible for you to display expressions and their current values, and set breakpoints on an expression. This window is activated when you choose Watch from the Window Menu, Debugger Window. Visual FoxPro enables IntelliSense in the Watch window but limits support to only List Members. 

In Visual FoxPro 9.0, the Find and Find Again menu items are available to search for items in the Name column of the Watch window.

Watch 
The value or expression you want to examine. Type expressions here to add them to the grid of active watch expressions below.

Name 
Displays the names of the current watch expressions.

Value 
Displays the values of the current watch expressions.

Type 
Displays characters that represent the data types of the current watch expressions.

You can select expressions, delete them, or add breakpoints to them.

To create a new watch expression 
Select text in any Visual FoxPro window and drag it to the Watch window.

To edit a watch expression 
Double-click the watch expression.

See Also
Reference
Debugger Window
Debugger Keyboard Shortcuts and Menus
Call Stack Window (Visual FoxPro)

Other Resources
Windows (Visual FoxPro)


 © Microsoft Corporation. All rights reserved. 

#4


Watch Window
Home Page (Debugger) |  Overview |  How Do I... Topics 

Use the Watch window to specify variables and expressions that you want to watch while debugging your program. You can also modify the value of a variable using the Watch window.

The Watch window contains four tabs: Watch1, Watch2, Watch3, and Watch4 — Each tab displays a user-specified list of variables and expressions in a spreadsheet field. You can group variables that you want to watch together onto the same tab. For example, you could put variables related to a specific window on one tab and variables related to a dialog box on another tab. You could watch the first tab when debugging the window and the second tab when debugging the dialog box.

If you add an array, object, or structure variable to the Watch window, plus sign (+) or minus sign (–) boxes appear in the Name column. You can use these boxes to expand or collapse your view of the variable, as described in Spreadsheet Fields.

If the value of a variable appears in red, it indicates that the value has recently changed. Only the last value to change appears in red. 

If the variable is an object, reference or a C++ pointer to an object, the Watch window automatically expands the variable to show the most important data at the top level. For example, suppose you had the following C++ object:

CString String  =   {...}
char *   m_pchData =0x7ffdf000 "abc"
   int          m_nDataLength=4
   int          m_nAllocLength=1244628

The Watch window displays the following:

String  =   {"abc"}

If the variable is a reference or a C++ pointer to an object, the Watch window automatically downcasts the reference or pointer. The Watch window adds an extra member to the expanded object. This extra member, which looks like another base class, indicates the derived subclass. For example, if a variable declared as a C++ pointer to CObject really points to a CComboBox, the Watch window recognizes this fact and adds an extra member so that you can access the CComboBox members.

The Watch window displays values in their default format. You can change the display format (to display Unicode characters, for example) using formatting symbols. For details, see Symbols for Watch Variables.

Tip   The Watch window does not display variable type information. You can view information for a variable type by using the window’s property page.

What do you want to do?
View the value of a variable

Modify the value of a variable

#5


判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}

#6


引用 2 楼 sweetswing 的回复:
Quote: 引用 1 楼 zhao4zhong1 的回复:

初步理解了汇编,反了一下strcpy
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
初步理解了汇编,反了一下strcpy多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! 初步理解了汇编,反了一下strcpy

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。


求教一个不相关的问题,一段C代码,我想看看变量的值是如何变化的,调什么窗口?


自动窗口、局部变量窗口、监视窗口

#7


补充:鼠标在源代码中的变量名上长时间停留。

#1


初步理解了汇编,反了一下strcpy
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
初步理解了汇编,反了一下strcpy多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! 初步理解了汇编,反了一下strcpy

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

#2


引用 1 楼 zhao4zhong1 的回复:
初步理解了汇编,反了一下strcpy
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
初步理解了汇编,反了一下strcpy多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! 初步理解了汇编,反了一下strcpy

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。


求教一个不相关的问题,一段C代码,我想看看变量的值是如何变化的,调什么窗口?

#3


      Visual FoxPro 9.0 SP2  
Watch Window (Visual FoxPro)  
See Also  
 Language Filter: All Language Filter: Multiple Language Filter: Visual Basic Language Filter: C# Language Filter: C++ Language Filter: J# Language Filter: JScript  
 Visual Basic (Declaration) 
 Visual Basic (Usage) 
 C# 
 C++ 
 J# 
 JScript 

Makes it possible for you to display expressions and their current values, and set breakpoints on an expression. This window is activated when you choose Watch from the Window Menu, Debugger Window. Visual FoxPro enables IntelliSense in the Watch window but limits support to only List Members. 

In Visual FoxPro 9.0, the Find and Find Again menu items are available to search for items in the Name column of the Watch window.

Watch 
The value or expression you want to examine. Type expressions here to add them to the grid of active watch expressions below.

Name 
Displays the names of the current watch expressions.

Value 
Displays the values of the current watch expressions.

Type 
Displays characters that represent the data types of the current watch expressions.

You can select expressions, delete them, or add breakpoints to them.

To create a new watch expression 
Select text in any Visual FoxPro window and drag it to the Watch window.

To edit a watch expression 
Double-click the watch expression.

See Also
Reference
Debugger Window
Debugger Keyboard Shortcuts and Menus
Call Stack Window (Visual FoxPro)

Other Resources
Windows (Visual FoxPro)


 © Microsoft Corporation. All rights reserved. 

#4


Watch Window
Home Page (Debugger) |  Overview |  How Do I... Topics 

Use the Watch window to specify variables and expressions that you want to watch while debugging your program. You can also modify the value of a variable using the Watch window.

The Watch window contains four tabs: Watch1, Watch2, Watch3, and Watch4 — Each tab displays a user-specified list of variables and expressions in a spreadsheet field. You can group variables that you want to watch together onto the same tab. For example, you could put variables related to a specific window on one tab and variables related to a dialog box on another tab. You could watch the first tab when debugging the window and the second tab when debugging the dialog box.

If you add an array, object, or structure variable to the Watch window, plus sign (+) or minus sign (–) boxes appear in the Name column. You can use these boxes to expand or collapse your view of the variable, as described in Spreadsheet Fields.

If the value of a variable appears in red, it indicates that the value has recently changed. Only the last value to change appears in red. 

If the variable is an object, reference or a C++ pointer to an object, the Watch window automatically expands the variable to show the most important data at the top level. For example, suppose you had the following C++ object:

CString String  =   {...}
char *   m_pchData =0x7ffdf000 "abc"
   int          m_nDataLength=4
   int          m_nAllocLength=1244628

The Watch window displays the following:

String  =   {"abc"}

If the variable is a reference or a C++ pointer to an object, the Watch window automatically downcasts the reference or pointer. The Watch window adds an extra member to the expanded object. This extra member, which looks like another base class, indicates the derived subclass. For example, if a variable declared as a C++ pointer to CObject really points to a CComboBox, the Watch window recognizes this fact and adds an extra member so that you can access the CComboBox members.

The Watch window displays values in their default format. You can change the display format (to display Unicode characters, for example) using formatting symbols. For details, see Symbols for Watch Variables.

Tip   The Watch window does not display variable type information. You can view information for a variable type by using the window’s property page.

What do you want to do?
View the value of a variable

Modify the value of a variable

#5


判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}

#6


引用 2 楼 sweetswing 的回复:
Quote: 引用 1 楼 zhao4zhong1 的回复:

初步理解了汇编,反了一下strcpy
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

对学习编程者的忠告:
初步理解了汇编,反了一下strcpy多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步Debug版对应汇编一行!
单步Debug版对应汇编千行不如单步Release版对应汇编一行!
不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他! 初步理解了汇编,反了一下strcpy

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。


求教一个不相关的问题,一段C代码,我想看看变量的值是如何变化的,调什么窗口?


自动窗口、局部变量窗口、监视窗口

#7


补充:鼠标在源代码中的变量名上长时间停留。