[section .text]
global _start
charact db 'a'
_start:
MOV ECX,charact
PUSH ECX
CALL usestack
POP ECX
MOV EDX,1
MOV EBX,1
MOV EAX,4
INT 0X80
MOV EAX,1
MOV EBX,0
INT 0X80
usestack:
MOV EBP, ESP
PUSHAD
INC word[EBP+4]
POPAD
RET
这个程序会得到随机字符,因为EBP中放的是charact的地址,INC word[EBP+4],这里把地址加1,得到未知地址,所以有随机字符产生。改为以下2条语句,这个问题解决:MOV EBP,DWORD[EBP+4] ;得到charact的地址,存入EBP
INC WORD[EBP] ;对charact的值加1
这样改了以后,通过ald调试,可以看到执行过程中各个寄存器的值是对的,但是,程序不能执行,会提示段错误。这时可以将charact的定义放到数据段.data中,来解决这个问题。所以,最后的程序是这样的:
[section .data]
charact db 'a' ;这里,'a'的地址是0X80490B8
[section .text]
global _start
_start:
MOV ECX,charact ;ESP=0XBFFFE040 EBP=0 ECX=0X80490B8
PUSH ECX ;ESP=0XBFFFE03C EBP=0 ECX=0X80490B8
CALL usestack ;ESP=0XBFFFE038 EBP=0 ECX=0X80490B8
POP ECX ;ESP=0XBFFFE040 EBP=0XBFFFE038 ECX=0X80490B8
MOV EDX,1
MOV EBX,1
MOV EAX,4
INT 0X80
MOV EAX,1
MOV EBX,0
INT 0X80
usestack:
MOV EBP, ESP ;ESP=0XBFFFE038 EBP=0XBFFFE038 ECX=0X80490B8
PUSHAD ;ESP=0XBFFFE018 EBP=0XBFFFE038 ECX=0X80490B8
MOV EBP,DWORD[EBP+4] ;ESP=0XBFFFE018 EBP=0X80490B8 ECX=0X80490B8
INC WORD[EBP] ;ESP=0XBFFFE018 EBP=0X80490B8 ECX=0X80490B8
POPAD ;ESP=0XBFFFE038 EBP=0XBFFFE038 ECX=0X80490B8
RET ;ESP=0XBFFFE03C EBP=0XBFFFE038 ECX=0X80490B8
后面的寄存器内容是用ALD(Assembly Language Debugger)调试得到的。ALD是一款LINUX下的调试器。
这里要注意的是,CALL和RET的时候也有压栈出栈操作。
如果不用数据段,而直接用命令:MOV ECX,charact,则程序运行过程会看得更清楚,特别是INC WORD[EBP] 这句话。因为传递的是值而不是地址,加1的操作看得会更清楚。