发布网友 发布时间:2022-04-20 16:00
共3个回答
热心网友 时间:2023-05-02 08:24
以下是综合你要求的示例,希望对你有帮助!!
;ex8.asm(e:\masm\base) 结构体应用示例。
.386
.model flat, stdcall
option casemap :none
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
.data
;COORD STRUCT ;windows.inc 文件中有定义
; x WORD ?
; y WORD ?
;COORD ENDS
buffer db 80 p(0)
CapMsg db '输出',0
szFmt db 'stPos.x 的和 = %d, stPos.y 的和 = %d',0
stPos1 COORD <4,8> ;定义结构体变量并初始化
stPos2 COORD <> ;定义结构体变量(取结构体原初始值)
stPos3 COORD {2,4} ;定义结构体变量并初始化
stPos4 COORD {,40} ;定义结构体变量并初始化
stPos COORD 10 p(<0,0>) ;定义结构体数组
.code
start:
mov stPos2.x, 10 ;域的使用
mov stPos2.y, 20
mov ecx,10
mov edi,offset stPos ;edi指向结构体变量
mov eax,1
mov ebx,11
@@:
mov (COORD ptr[edi]).x, ax
mov (COORD ptr[edi]).y, bx
add edi,type COORD ;结构体的大小
inc ax
inc bx
loop short @B
xor eax,eax
xor ebx,ebx
mov ecx,10
mov edi,offset stPos ;edi指向结构体变量
@@:
add ax,(COORD ptr[edi]).x
add bx,(COORD ptr[edi]).y
add edi,type COORD ;结构体的大小
loop short @B
invoke wsprintf, ;格式化信息串
addr buffer, ;信息串格式化后的存放地
addr szFmt, ;信息串的格式
eax,
ebx
invoke MessageBox, ;显示信息框
NULL, ;父窗口句柄
offset buffer, ;正文串
offset CapMsg, ;抬头串
MB_OK ;按钮"确定"
INVOKE ExitProcess,0 ;结束进程
end start
参考资料:
1、结构类型的定义
用STRUC和ENDS可以把一系列数据定义语句括起来作为一种新的、用户定义的结构类型。其一般说明格式如下:
结构名 STRUC [Alignment][, NONUNIQUE]
数据定义语句序列
结构名 ENDS
解释:结构名是一个合法的标识符,且具有唯一性。结构名代表整个结构类型,前后两个结构名必须一致。结构内被定义的变量为结构字段,变量名即为字段名。
一个结构中允许含有任意多个字段,各字段的类型和所占字节数也都可任意。如果字段有字段名,则字段名必须唯一。每个字段可存取。
对齐方式(Alignment):可用1、2或4来指定结构中字段的字节边界(Byte boundary),其缺省值为1。见4.3.2节中的有关叙述;
NONUNIQUE:要求结构中的字段必须用全名才能访问,见本小节中的“结构类型字段的引用”。
例如:
COURSE
STRUC 在左上例中,COURSE是结构名,它含有三个字段:NO、CNAME和SCORE,它们的类型分别是DD、DB和DW。
NO DD ?
CNAME DB 'Assember'
SCORE DW 0
COURSE
ENDS
上例中,COURSE是结构名,它含有三个字段:NO、CNAME和SCORE,这些字段的类型分别是DD、DB和DW。
结构类型COURSE共占14个字节,其字段NO、CNAME和SCORE的偏移量分别为:0、4和12。
结构中的字段可以有字段名,也可以没有字段名。有字段名的字段可直接用该字段名来访问它,没有字段名的字段可以用该字段在结构中的偏移量来访问。
例如:
PEASON
STRUC
NO DD ? ;偏移量为0
NAME DB 10 p (?) ;偏移量为4
DB 1 ;偏移量为14
PEASOM
ENDS
在结构PEASON中,有二个字段有字段名,一个字段没有字段名,但不管有无字段名,我们都可用其偏移量来访问它。
2、结构类型变量的定义
在定义某个结构类型后,程序员就可以说明该结构类型的内存变量。它的说明形式与前面介绍的简单数据类型的变量说明基本上一致。其定义格式如下:
[变量名] 结构名 <[字段值表]>
解释:1)、
变量名即为该结构类型的变量名,它可省缺。如果省缺,则不能用符号名来访问该内存单元;
2)、 字段值表是给字段赋初值,中间用逗号','分开,其字段值的排列顺序及类型应与该结构说明时各字段相一致;
3)、 如果结构变量中某字段用其说明时的缺省值,那么,可用逗号来表示;如果所有字段都如此,则可省去字段值表,但必须保留一对尖括号"<"、">"。
例如:
COURSE1
COURSE <> ;使用缺省的初值
COURSE2 COURSE <1, 'Pascal', 60>
COURSE3 COURSE <2, , 84> ;使用缺省的课程名
PEASON1 PEASON <1000, '张 三', 34>
3、结构类型字段的引用
定义了结构类型的变量后,若要访问其结构中的某个字段,则可采用如下形式:
结构变量名.字段名
该引用方式与高级语言的字段引用方式完全一致,我们还可用偏移量来访问其中的某个字段,但此方法不直观,变动性大,所以,一般情况下,不提倡使用此方法。
例如:
EXAM1 STRUC
F1 DW ?
F2 DB ?
EVEN ;偶对齐
F3 DW ?
EXAM1 ENDS
E1 EXAM1 <1234H,'A',8765H> ;定义结构EXAM1的一个变量E1
下面二种方法都可以把结构变量E1中字段的内容赋给寄存器AX,但如果在字段F3之前增加或减少了字段,那么,这些引用需要改变吗?
(1)、用字段名直接引用
MOV AX, E1.F3
(2)、用字段的偏移量间接引用
LEA SI, E1
MOV AX, [SI+4] ;其中4是字段F3的偏移量
热心网友 时间:2023-05-02 08:24
; 本程序通过编译,运行正确
Code Segment
Assume CS:Code,DS:Code
; -------------------------------------
; 定义结构体类型
My_Info STRUC
x db 8 p(?);学号
y db 18 p(?) ;姓名
My_Info ENDS
; -------------------------------------
; 定义结构体类型变量或数组
Students My_Info <'12345678','Wang Ming'>
My_Info <'12345679','Li Li Ying'>
My_Info <'21345678','Zhao Dong Qing'>
; -------------------------------------
Start: push cs
pop ds
push cs
pop es ;使数据段、附加段与代码段同段
lea bx,Students ;结构体类型数组地址
mov cx,3 ;数组元素个数
Read_Item: push cx
lea si,[bx.x] ;学号地址
push bx
xor bx,bx
mov cx,size x ;学号长度
Disp_x: mov dl,[si][bx] ;取一个字符
inc bx
test dl,dl
jnz $+4
mov dl,20h
mov ah,2 ;显示输出一个字符
int 21h
loop Disp_x
mov dl,20h
mov ah,2
int 21h
pop bx
lea si,[bx.y] ;姓名地址
push bx
xor bx,bx
mov cx,size y ;姓名长度
Disp_y: mov dl,[si][bx] ;取一个字符
inc bx
test dl,dl
jnz $+4
mov dl,20h
mov ah,2
int 21h
loop Disp_y
pop bx
add bx,type My_Info ;下一个数组元素地址(type My_Info=结构体类型长度)
mov dl,13 ;输出一个回车符
mov ah,2
int 21h
mov dl,10 ;输出一个换行符
mov ah,2
int 21h
pop cx
loop Read_Item
Exit_Proc: mov ah,4ch ;结束程序
int 21h
Code ENDS
END Start ;编译到此结束
热心网友 时间:2023-05-02 08:25
@@:
mov ax,(COORD ptr[edi]).x
mov bx,(COORD ptr[edi]).y
add edi,type COORD ;结构体的大小
loop short @B
@@:
add ax,(COORD ptr[edi]).x
add bx,(COORD ptr[edi]).y
add edi,type COORD ;结构体的大小
loop short @B
这里要改成
ax,(COORD ptr stPos [edi]).x
bx,(COORD ptr stPos [edi]).y
而且edi开始应该设置成数组索引才对
edi换成地址编译器不会报错但程序一定会出错