偶然看到Allan Ruin大大的某post,原意大概是:子函数内的局部变量没有初始化的话,其值应该是任意的,函数返回后会释放内存。但是为什么第二次调用的时候i的值会是777呢?之前没遇到过类似问题,毕竟是现实中不会出现的情况。但通过汇编代码大概可以研究一下的吧?
这段时间刚好在看CSAPP的GAS语法汇编,恰好拿来练手的说。
C代码如下: 版权属于Allan Ruin :)
#include <stdio.h>
void foo(void)
{
int i;
printf("%d\n", i);
i = 777;
}
int main(void)
{
foo();
foo();
return 0;
}
ouput:
3
777
gcc -s lg_test.c
汇编代码如下
.file "lg_test.c"
.section .rodata ;read only data segment
.LC0:
.string "%d\n" ;printf() function's first parameter
.text
.globl foo
.type foo,@function
foo:
1 pushl %ebp ;save old %ebp
2 movl %esp, %ebp ;new %ebp point to old %ebp (i.e. frame pointer)
3 subl $40, %esp ;allocate 40 bytes on stack
4 movl $.LC0, %eax ;move the string"%d\n" to %eax
5 movl -12(%ebp), %edx ;use -12(%ebp) as i's value and save in %edx
6 movl %edx, 4(%esp) ;set -12(%ebp) as the second parameter,push in stack
7 movl %eax, (%esp) ;set %eax( i.e. "%d\n" ) as the first parameter
8 call printf ;call printf function(you can assume that
;it doesn't affect the existing stack frame)
9 movl $777, -12(%ebp) ;NOTE: -12 (%ebp) has changed
10 leave ;i.e. movl %ebp, %esp ; pop %ebp ;
11 ret ;return i.e. pop %eip ;
2012年4月15日星期日
2012年1月26日星期四
assembly language 实验九中的问题
在屏幕中间分别显示三种颜色的字符串“welcome to MASM”
80 * 25的彩色字符显示缓冲区
代码:
data segment
db 'welcome to MASM!'
db 02h,01h,04h
data ends
stack segment
dw 8 dup(0)
stack ends
code segment
assume cs:code,ds:data,ss:stack
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,10h
mov bx,[11*160]
mov di,0
mov ax,0b800h
mov cx,3 ;outer loop
s1: push cx
push ax
push di
mov es,ax
mov si,0
mov di,0
mov cx,16
s2: mov al,ds:[di]
mov es:[bx+si],al
inc di
add si,2
loop s2 ;set the even byte in display memory
mov si,1 ;odd byte
pop di ;set color
mov al,ds:[16+di] ;load color
mov cx,16
s3: mov es:[bx+si],al
add si,2
loop s3
;ready for next turn
inc di ;next color style
pop ax
add ax,0ah
;add bx,160 ;next row
pop cx
loop s1
mov ah,4ch
int 21h
code ends
end start
这个是显示正常的,通过修改ax来改段地址(绿色字体),已达到指向下一行的目的。但是,我原先的想法是通过改变bx的值来指向下一行(红色字体),不知何故没有显示正常。。。囧
但是理论上应该是一样的啊??bx自增160到下一行的行首,和ax自增16效果应该是一样的啊。。。这里面有什么玄机?debug了好久也没找出来,菜了。。。。囧
80 * 25的彩色字符显示缓冲区
代码:
data segment
db 'welcome to MASM!'
db 02h,01h,04h
data ends
stack segment
dw 8 dup(0)
stack ends
code segment
assume cs:code,ds:data,ss:stack
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,10h
mov bx,[11*160]
mov di,0
mov ax,0b800h
mov cx,3 ;outer loop
s1: push cx
push ax
push di
mov es,ax
mov si,0
mov di,0
mov cx,16
s2: mov al,ds:[di]
mov es:[bx+si],al
inc di
add si,2
loop s2 ;set the even byte in display memory
mov si,1 ;odd byte
pop di ;set color
mov al,ds:[16+di] ;load color
mov cx,16
s3: mov es:[bx+si],al
add si,2
loop s3
;ready for next turn
inc di ;next color style
pop ax
add ax,0ah
;add bx,160 ;next row
pop cx
loop s1
mov ah,4ch
int 21h
code ends
end start
这个是显示正常的,通过修改ax来改段地址(绿色字体),已达到指向下一行的目的。但是,我原先的想法是通过改变bx的值来指向下一行(红色字体),不知何故没有显示正常。。。囧
但是理论上应该是一样的啊??bx自增160到下一行的行首,和ax自增16效果应该是一样的啊。。。这里面有什么玄机?debug了好久也没找出来,菜了。。。。囧
订阅:
博文 (Atom)

