今天继续用MASM32编写调用Windows API函数GetNativeSystemInfo来检测Windows操作系统是32位还是64位的程序。

修改完善形成了下面的代码:

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; 32or64.asm
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<.586
.model     flat, stdcall
option     casemap:none
include    \masm32\include\windows.inc
include    \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include    \masm32\include\user32.inc
includelib \masm32\lib\user32.lib;sssssssssssssssssssssssssssssssssssssss
;.const
;sssssssssssssssssssssssssssssssssssssss
;PROCESSOR_ARCHITECTURE_INTEL   equ 0      ;x86
;PROCESSOR_ARCHITECTURE_ARM     equ 5      ;ARM
;PROCESSOR_ARCHITECTURE_IA64    equ 6      ;基于 Intel Itanium 的
;PROCESSOR_ARCHITECTURE_AMD64   equ 9      ;x64 (AMD 或 Intel)
PROCESSOR_ARCHITECTURE_ARM64   equ 12     ;ARM64
;PROCESSOR_ARCHITECTURE_UNKNOWN equ 0ffffh ;未知体系结构。_SYSTEM_INFO STRUCTUNIONdwOemId DWORD ?STRUCTwProcessorArchitecture        WORD       ?wReserved                     WORD       ?ENDSENDSdwPageSize                    DWORD      ?lpMinimumApplicationAddress   DWORD      ?lpMaximumApplicationAddress   DWORD      ?dwActiveProcessorMask         DWORD      ?dwNumberOfProcessors          DWORD      ?dwProcessorType               DWORD      ?dwAllocationGranularity       DWORD      ?wProcessorLevel               WORD       ?wProcessorRevision            WORD       ?
_SYSTEM_INFO ENDS;sssssssssssssssssssssssssssssssssssssss
.data
;sssssssssssssssssssssssssssssssssssssss
g_szCaption                 db    "Windows",0
g_sz32Bit                   db    "32位",0
g_sz64Bit                   db    "64位",0
g_szGetNativeSystemInfo     db    "GetNativeSystemInfo", 0
g_szkernel32Dll             db    "kernel32.dll", 0
g_szFailGetModuleHandle     db    "GetModuleHandle失败", 0
g_szFailGetProcAddress      db    "GetProcAddress失败", 0
g_szFailGetNativeSystemInfo db    "GetNativeSystemInfo失败", 0
g_lpfnGetNativeSystemInfo   dword ?
g_lpSI                      dword ?  ; SYSTEM_INFO;sssssssssssssssssssssssssssssssssssssss
.code
;sssssssssssssssssssssssssssssssssssssss
start:invoke GetModuleHandle, OFFSET g_szkernel32Dll.if    eax==NULLmov eax, OFFSET g_szFailGetModuleHandle.elseinvoke GetProcAddress, eax, OFFSET g_szGetNativeSystemInfo.IF eax==NULLmov eax, OFFSET g_szFailGetProcAddress.ELSEmov   g_lpfnGetNativeSystemInfo, eaxpush  offset g_lpSIcall  g_lpfnGetNativeSystemInfomov   eax, g_lpSImovzx eax,  (SYSTEM_INFO ptr [eax]).wProcessorArchitecture.if (eax==PROCESSOR_ARCHITECTURE_IA64) || (eax==PROCESSOR_ARCHITECTURE_AMD64) || (eax==PROCESSOR_ARCHITECTURE_ARM64)mov eax, OFFSET g_sz64Bit.elsemov eax, OFFSET g_sz32Bit.endif.ENDIF.endifinvoke MessageBox, NULL, eax, OFFSET g_szCaption, MB_OKinvoke ExitProcess, NULL
end start

代码顺利汇编和连接,生成了EXE,但运行时出错:

用OllDbg跟踪调试:

引发问题的代码是:

movzx eax,  (SYSTEM_INFO ptr [eax]).wProcessorArchitecture

回溯起来问题出在上一行代码:

mov   eax, g_lpSI

根源则在于汇编程序中的寻址方式,由于SYSTEM_INFO结构体的定义是公开透明的,我们可以手工算出成员的偏移地址来进行访问,但为了保证通用性和灵活性,一般我们是用基址+变址的方式来访问结构体成员的,把代码改成:

mov   eax, offset g_lpSI

这样程序就能顺利运行并给出结果:

再进一步完善:

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; FileName: CpuArch.asm
; Function: Show CPU Architecture with API GetNativeSystemInfo
;   Author: PurpleEndurer
;   DevEnv: Windows 7 Ultimate 64bit + MASM32
;
; Log:
;---------------------------------------------------------------
;  20221126 Created
;  20221127 Added c_showMoreInfo, getCpuArcInfo(), OK!
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.586
.model     flat, stdcall
option     casemap:none
include    \masm32\include\windows.inc
include    \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include    \masm32\include\user32.inc
includelib \masm32\lib\user32.lib;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
;proto
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
_GetNativeSystemInfo    TYPEDEF proto :DWORD
lpfnGetNativeSystemInfo TYPEDEF Ptr _GetNativeSystemInfogetCpuArcInfo           proto;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
;.const
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
;PROCESSOR_ARCHITECTURE_INTEL   equ 0      ;x86
;PROCESSOR_ARCHITECTURE_ARM     equ 5      ;ARM
;PROCESSOR_ARCHITECTURE_IA64    equ 6      ;基于 Intel Itanium 的
;PROCESSOR_ARCHITECTURE_AMD64   equ 9      ;x64 (AMD 或 Intel)
PROCESSOR_ARCHITECTURE_ARM64    equ 12     ;ARM64
;PROCESSOR_ARCHITECTURE_UNKNOWN equ 0ffffh ;未知体系结构。
c_showMoreInfo                  equ 1_SYSTEM_INFO STRUCTUNIONdwOemId DWORD ?STRUCTwProcessorArchitecture        WORD       ?wReserved                     WORD       ?ENDSENDSdwPageSize                    DWORD      ?lpMinimumApplicationAddress   DWORD      ?lpMaximumApplicationAddress   DWORD      ?dwActiveProcessorMask         DWORD      ?dwNumberOfProcessors          DWORD      ?dwProcessorType               DWORD      ?dwAllocationGranularity       DWORD      ?wProcessorLevel               WORD       ?wProcessorRevision            WORD       ?
_SYSTEM_INFO ENDS;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
.data
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
g_szCaption                 db    "Windows",0
g_szGetNativeSystemInfo     db    "GetNativeSystemInfo", 0
g_szkernel32Dll             db    "kernel32.dll", 0
g_szFailGetModuleHandle     db    "GetModuleHandle失败", 0
g_szFailGetProcAddress      db    "GetProcAddress失败", 0
g_szFailGetNativeSystemInfo db    "GetNativeSystemInfo失败", 0if  c_showMoreInfo eq 0g_sz32Bit                          db "32位",0g_sz64Bit                          db "64位",0
elseg_szPROCESSOR_ARCHITECTURE_INTEL   db "x86", 0               ; equ 0g_szPROCESSOR_ARCHITECTURE_ARM     db "ARM", 0               ; equ 5g_szPROCESSOR_ARCHITECTURE_IA64    db "IA64",0               ;equ 6,基于 Intel Itanium 的g_szPROCESSOR_ARCHITECTURE_AMD64   db "x64 (AMD 或 Intel)", 0; equ 9g_szPROCESSOR_ARCHITECTURE_ARM64   db "ARM64", 0             ;equ 12g_szPROCESSOR_ARCHITECTURE_UNKNOWN db "Unknown", 0           ;equ 0ffffh,未知体系结构。
endif ;c_showMoreInfog_lpfnGetNativeSystemInfo   lpfnGetNativeSystemInfo ? ; dword ?
g_lpSI                      dword ?  ; SYSTEM_INFO;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
.code
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
start:invoke GetModuleHandle, OFFSET g_szkernel32Dll.if    eax==NULLmov eax, OFFSET g_szFailGetModuleHandle.elseinvoke GetProcAddress, eax, OFFSET g_szGetNativeSystemInfo.IF eax==NULLmov   eax, OFFSET g_szFailGetProcAddress.ELSEmov    g_lpfnGetNativeSystemInfo, eax;push   OFFSET g_lpSI;call   g_lpfnGetNativeSystemInfoinvoke g_lpfnGetNativeSystemInfo, OFFSET g_lpSImov   eax, OFFSET g_lpSI ; mov   eax, g_lpSI will cause an exception!movzx  eax,  [eax+SYSTEM_INFO.wProcessorArchitecture]    ;movzx eax,  (SYSTEM_INFO ptr [eax]).wProcessorArchitectureinvoke getCpuArcInfo.ENDIF.endifinvoke MessageBox, NULL, eax, OFFSET g_szCaption, MB_OKinvoke ExitProcess, NULLgetCpuArcInfo proc ; dwCpuArc: dword
; input : eax=CpuArchitecture
; Output: eax=offset address of Cpu Architecture infomation string
IF  c_showMoreInfo eq 0.if (eax==PROCESSOR_ARCHITECTURE_IA64) || (eax==PROCESSOR_ARCHITECTURE_AMD64) || (eax==PROCESSOR_ARCHITECTURE_ARM64)mov eax, OFFSET g_sz64Bit.elsemov eax, OFFSET g_sz32Bit.endif
ELSE.if eax==PROCESSOR_ARCHITECTURE_INTELmov eax, OFFSET g_szPROCESSOR_ARCHITECTURE_INTEL.elseif eax==PROCESSOR_ARCHITECTURE_ARMmov eax, OFFSET g_szPROCESSOR_ARCHITECTURE_ARM.elseif eax==PROCESSOR_ARCHITECTURE_IA64mov eax, OFFSET g_szPROCESSOR_ARCHITECTURE_IA64.elseif eax==PROCESSOR_ARCHITECTURE_AMD64mov eax, OFFSET g_szPROCESSOR_ARCHITECTURE_AMD64.elseif eax==PROCESSOR_ARCHITECTURE_ARM64mov eax, OFFSET g_szPROCESSOR_ARCHITECTURE_ARM64.elsemov eax, OFFSET g_szPROCESSOR_ARCHITECTURE_UNKNOWN.endif
ENDIF ;c_showMoreInfo    ret
getCpuArcInfo endpend start

程序运行结果:

如果用C++来完成,就没有这么折腾了,用Microsoft Visual Studio  2019来实现的代码如下:

// 32or64.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include "pch.h"
#include "windows.h"
#include <iostream>
#include "sysinfoapi.h"int main()
{SYSTEM_INFO si;int         iCpuArc;GetNativeSystemInfo(&si);iCpuArc = si.wProcessorArchitecture;std::cout << "si.wProcessorArchitecture=";std::cout << iCpuArc;std::cout << "\nArchitecture:";switch (iCpuArc){case PROCESSOR_ARCHITECTURE_INTEL:std::cout << "x86\n";break;case PROCESSOR_ARCHITECTURE_ARM:std::cout << "ARM\n";break;case PROCESSOR_ARCHITECTURE_IA64:std::cout << "IA64\n";break;case PROCESSOR_ARCHITECTURE_AMD64:std::cout << "x64 (AMD 或 Intel)\n";break;case PROCESSOR_ARCHITECTURE_ARM64:std::cout << "ARM64\n";break;default:std::cout << "UNKNOWN\n";}
}// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单// 入门使用技巧:
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

运行结果如下:

MASM32编程访问结构体成员要注意的一点相关推荐

  1. C/C++ 中访问结构体成员的方法

    先看例子:  1#include <stdio.h> 2void main(){ 3    typedef struct {     4     int int_field;      5 ...

  2. C语言中访问结构体成员时 点 . 和 箭头 - 的区别

    点(.)是用于结构体变量访问成员,箭头(->)是用于结构体指针访问成员. 例如: #include <stdio.h>int main(void) {struct Smy {int ...

  3. C语言结构体变量 指针以及对结构体成员的访问

    文章目录 结构体 结构体变量访问成员的方法 结构体指针变量访问成员的方法 结构体 struct AGE {int year;int month;int day; }; struct STUDENT { ...

  4. c语言结构体成员变量私有化,C语言中结构体变量私有化详解

    C语言中结构体变量私有化详解 背景介绍 操作系统 : CentOS7.3.1611_x64 gcc版本 :4.8.5 什么是结构体? 在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚 ...

  5. Go的反射是如何获取结构体成员信息的?

    前言 哈喽,大家好,今天这篇文章的目的主要是解答一位读者的疑问,涉及知识点是反射和结构体内存布局.我们先看一下读者的问题: img 我们通过两个问题来解决他的疑惑: 结构体在内存中是如何存储的 反射获 ...

  6. C语言:指针的偏移步长、结构体成员的偏移量、嵌套结构体成员的偏移量、结构体的内存对齐

    文章目录 1 不同类型指针的偏移步长 2 结构体成员的偏移量 3 嵌套结构体成员的偏移量 4 结构体的内存对齐 4.1 内存对齐的原因与优点 4.2 结构体内存对齐的规则 4.3 结构体嵌套结构体时的 ...

  7. 结构体成员的引用方法

    结构体成员变量的引用 结构体变量名.成员名 student.num=10010; "."是成员运算符,它在所有的运算符中优先级最高. 结构体指针:指向结构体变量的指针,一个结构体变 ...

  8. 宏定义来实现一个结构体成员相对于该结构体首地址的偏移量

    #define my_offerset(type , exp) ((int)&(((type*)0)->exp))//因为是求结构体的成员内存偏移.结构体会定义一种新的数据类型 所以ty ...

  9. 结构体成员数组不定长如何实现

    [目的] 定义一个结构体类,其中的成员变量数组长度不定,根据实例化的对象指定长度,所以想到用指针实现 [现状] 指针可以指向任意长度数组,但结构体类只分配指针本身4字节长度,所以无法扩展 1 /** ...

最新文章

  1. 为什么有些老板要注册很多家公司
  2. 8个必备的PHP功能开发
  3. CPU 有个禁区,内核权限也无法进入!
  4. linux下单节点oracle数据库间ogg搭建
  5. mvn 打包项目到eclipse
  6. 3.6 mkpasswd命令
  7. SpringBoot启动banner更改
  8. python导入模块报错_Python 导入上层目录模块报错
  9. LeetCode 98. 验证二叉搜索树 思考分析
  10. html服务器框架,一种类似http/html的分布式GUI程序设计框架
  11. 斐波那契数列 青蛙跳台阶 变态跳台阶
  12. C++学习之CodeBlocks安装与调试
  13. node.js用get方式获取网页中的链接
  14. Macbook pro笔记本键盘失灵了(u,i,o,j,k,l,k,m无效了)解决办法
  15. 对于 Redux 的理解
  16. python关键词提取_如何从Python格式字符串中提取关键字? - python
  17. 喜欢的数字:使用一个字典来_数字证书:何时何地使用它们
  18. 我靠这个数据分析利器,3年当上运营主管
  19. 安装自己写的插件时,报插件版本过高,请升级JAR包或者安装低版本插件的问题
  20. 解决git 命令出现end问题

热门文章

  1. 记录使用到的正则表达式
  2. Go 1.19.3 sync.Mutex原理简析
  3. Cygwin环境的搭建
  4. canvas中添加html,如何在DIV中添加html5 CANVAS
  5. 解码奇安信2021年业绩预告传递的几个信息,2022更值得期待
  6. 虚幻引擎(15)-暂停游戏
  7. Android 设置字体样式
  8. 腊月廿六链界观区块链资讯
  9. 如何在 Word 中检查语法、拼写?
  10. springcloud alibaba(一)nacos下载及简单使用