如何用Intel X86汇编语言计算员工结构体的薪资总和?
用Intel x86汇编计算员工薪资总和的实现方案
Got it, let's walk through exactly how to calculate the total salary of all employees using Intel x86 assembly. First, let's recap the data we're working with—you've got a Employee struct with a 20-byte name and 16-bit salary, an array of 4 employees, and a double-word variable sum to store the final total.
核心思路
The key steps are straightforward:
- Initialize a loop counter to iterate over every employee in the array
- Calculate the memory offset of each employee's
salaryfield - Accumulate each salary into the
sumvariable (handling 32-bit storage since sum is a double-word) - Exit the loop once all employees are processed
16-bit MASM 实现(DOS环境)
This version works for classic 16-bit DOS assembly, using segment registers and 16-bit operations:
.MODEL SMALL .STACK 100h .DATA ; 定义题目给出的结构体和数据 Employee struct name DB 20 dup(0) salary DW 0 Employee ends nrEmployees DW 4 Employees Employee {"Alex", 100}, {"Mike", 100}, {"Paul", 300}, {"Ana", 450} sum DD 0 .CODE MAIN PROC ; 初始化数据段寄存器(访问数据段的必要步骤) MOV AX, @DATA MOV DS, AX ; 初始化循环计数器和累加相关寄存器 XOR CX, CX ; CX = 0,作为循环计数器 XOR AX, AX ; AX临时存储单个员工的薪资 sum_loop: ; 检查是否遍历完所有员工:CX == nrEmployees? CMP CX, nrEmployees JE loop_end ; 相等则跳转到循环结束 ; 计算当前员工在数组中的偏移地址:CX * 结构体大小 MOV AX, CX MOV BX, SIZEOF Employee ; 自动获取结构体大小(22字节),避免硬编码 MUL BX MOV BX, AX ; BX现在是当前员工的起始偏移量 ; 取出当前员工的salary字段:起始偏移 + salary字段的偏移(20字节) MOV AX, [Employees + BX + OFFSET Employee.salary] ; 累加薪资到sum(双字变量,分高低16位处理进位) ADD WORD PTR sum, AX ; 先加低16位 ADC WORD PTR sum + 2, 0 ; 加上进位到高16位,防止溢出 ; 计数器加1,继续循环 INC CX JMP sum_loop loop_end: ; DOS环境下退出程序 MOV AH, 4Ch INT 21h MAIN ENDP END MAIN
32-bit MASM32 实现(平展内存模型)
If you're working in a 32-bit environment, the code becomes simpler thanks to 32-bit registers and flat memory addressing:
.386 .MODEL FLAT, C .DATA Employee struct name DB 20 dup(0) salary DW 0 Employee ends nrEmployees DWORD 4 Employees Employee {"Alex", 100}, {"Mike", 100}, {"Paul", 300}, {"Ana", 450} sum DWORD 0 .CODE _main PROC ; 初始化累加器和计数器 XOR EAX, EAX ; EAX存储总和,初始为0 XOR ECX, ECX ; ECX作为循环计数器 sum_loop: CMP ECX, nrEmployees JE loop_end ; 计算当前员工的内存地址:数组基址 + 计数器*结构体大小 MOV EDX, ECX IMUL EDX, SIZEOF Employee MOV BX, [Employees + EDX + OFFSET Employee.salary] ; 直接累加薪资到EAX(32位足够存储总和,无需拆分处理) ADD EAX, EBX INC ECX JMP sum_loop loop_end: MOV sum, EAX ; 把最终总和存入sum变量 RET _main ENDP END
关键注意事项
- 结构体大小计算: Always use
SIZEOF Employeeinstead of hardcoding 22 bytes—this makes your code maintainable if the struct changes later. - 32-bit存储处理: Since
sumis a double-word (32 bits), in 16-bit mode you need to useADC(add with carry) to handle overflow from the low 16 bits to the high 16 bits. - 循环边界: Make sure the loop runs exactly
nrEmployeestimes—usingCMP CX, nrEmployeesandJE loop_endensures you don't under/over iterate.
内容的提问来源于stack exchange,提问作者Alexei Postolachi
相关产品推荐
相关产品推荐

