求教:王爽老师汇编语言综合研究5的第二个程序,为什么可以用int,而不用char?

时间:2022-01-03 12:11:28
如下程序:
void showchar(int,int,...);
main()
{
 showchar(8,2,'a','b','c','d','e','f','g','h');
}
void showchar(int n,int color,...)
{
 int a;
 for(a=0;a!=n;a++)
 {
  *(char far *)(0xb8000000+160*10+80+a+a)=*( int *)(_BP+8+a+a);
  *(char far *)(0xb8000000+160*10+81+a+a)=color;
 }
}
标红的int类型,如果换成char,也是可以显示出一样的结果的。这里不懂,显示字符不是应该是char型的么,书上为什么用int型?
求教:王爽老师汇编语言综合研究5的第二个程序,为什么可以用int,而不用char?

11 个解决方案

#1


这类做法看着就晕。理解上的话,那是从堆栈里的参数区获得要显示的字符,那里原型定义和实际传输上就是 int 吧,为了一致这里也写常 int * 了?

#2


反正左值是*(char far *),右值用*(int *)还是*(char *)都一样,只会赋值一个字节数据过去,不过16位模式下压栈数据是16位,所以他就用了*(int *),可能是为了逻辑完美的强迫症吧,类似x86汇编jnz、jne实际生成同样的指令,但是两种助记符对应不同的语境。


#3


引用 2 楼 DelphiGuy 的回复:
反正左值是*(char far *),右值用*(int *)还是*(char *)都一样,只会赋值一个字节数据过去,不过16位模式下压栈数据是16位,所以他就用了*(int *),可能是为了逻辑完美的强迫症吧,类似x86汇编jnz、jne实际生成同样的指令,但是两种助记符对应不同的语境。

“不过16位模式下压栈数据是16位,所以他就用了*(int *),”这句话是什么意思?能再详细说一下么,感谢楼上的大侠

#4


意思是参数'a','b','c','d','e','f','g','h'每个在栈中都占16位空间,而不是8位。

#5


多问一下, 是不是只有0~0xff的数字才正好出现这种情况? 还有令我想到32位下也是用push eax,push ebx这种32位寄存器来传递参数的

#6


我想了想,我明白您的意思了,就是左边已经指明是1字节的数据了,右边就无所谓了。上边这个问题问的不好,没抓住要点

不过,因为“*(char far *)”这种用法很少见,能否还是请DelphiGuy大大解释一下这种用法,多谢:(

#7


char far *这只是16位模式下的远指针。

#8


嗯,是不是*(char *)就表示只能接受一个字节的传入?

#9


就是目标类型是char

#10


嗯,感谢DelphiGuy和zera大大
发现c语言的用法真的太精妙了,比如下面这句,紧靠等号左边的void是什么意思呢
void (*obf_funcs[]) (void) = {
        (void (*) (void))ensure_single_instance,
        (void (*) (void))table_unlock_val,
        (void (*) (void))table_retrieve_val,
        (void (*) (void))table_init, // This is the function we actually want to run
        (void (*) (void))table_lock_val,
        (void (*) (void))util_memcpy,
        (void (*) (void))util_strcmp,
        (void (*) (void))killer_init,
        (void (*) (void))anti_gdb_entry
    };

#11


C的 (void) 表示没有参数,C++中()和 (void) 是一样的,但是C的()表示可以有任意多个参数(0个或多个)。

#1


这类做法看着就晕。理解上的话,那是从堆栈里的参数区获得要显示的字符,那里原型定义和实际传输上就是 int 吧,为了一致这里也写常 int * 了?

#2


反正左值是*(char far *),右值用*(int *)还是*(char *)都一样,只会赋值一个字节数据过去,不过16位模式下压栈数据是16位,所以他就用了*(int *),可能是为了逻辑完美的强迫症吧,类似x86汇编jnz、jne实际生成同样的指令,但是两种助记符对应不同的语境。


#3


引用 2 楼 DelphiGuy 的回复:
反正左值是*(char far *),右值用*(int *)还是*(char *)都一样,只会赋值一个字节数据过去,不过16位模式下压栈数据是16位,所以他就用了*(int *),可能是为了逻辑完美的强迫症吧,类似x86汇编jnz、jne实际生成同样的指令,但是两种助记符对应不同的语境。

“不过16位模式下压栈数据是16位,所以他就用了*(int *),”这句话是什么意思?能再详细说一下么,感谢楼上的大侠

#4


意思是参数'a','b','c','d','e','f','g','h'每个在栈中都占16位空间,而不是8位。

#5


多问一下, 是不是只有0~0xff的数字才正好出现这种情况? 还有令我想到32位下也是用push eax,push ebx这种32位寄存器来传递参数的

#6


我想了想,我明白您的意思了,就是左边已经指明是1字节的数据了,右边就无所谓了。上边这个问题问的不好,没抓住要点

不过,因为“*(char far *)”这种用法很少见,能否还是请DelphiGuy大大解释一下这种用法,多谢:(

#7


char far *这只是16位模式下的远指针。

#8


嗯,是不是*(char *)就表示只能接受一个字节的传入?

#9


就是目标类型是char

#10


嗯,感谢DelphiGuy和zera大大
发现c语言的用法真的太精妙了,比如下面这句,紧靠等号左边的void是什么意思呢
void (*obf_funcs[]) (void) = {
        (void (*) (void))ensure_single_instance,
        (void (*) (void))table_unlock_val,
        (void (*) (void))table_retrieve_val,
        (void (*) (void))table_init, // This is the function we actually want to run
        (void (*) (void))table_lock_val,
        (void (*) (void))util_memcpy,
        (void (*) (void))util_strcmp,
        (void (*) (void))killer_init,
        (void (*) (void))anti_gdb_entry
    };

#11


C的 (void) 表示没有参数,C++中()和 (void) 是一样的,但是C的()表示可以有任意多个参数(0个或多个)。