首页
社区
课程
招聘
[求助]汇编编译器 的一些问题
发表于: 2008-12-11 11:24 4511

[求助]汇编编译器 的一些问题

2008-12-11 11:24
4511
刚开始学汇编的时候(王爽的书),用masm5.0+link3.6就能吧书上的代码跑起来
后来,看杨季文的80x86  看糊涂了

1: masm5.0只能编译16位的汇编,masm6.0以上编译的就是32位的了。
我有一个从实模式到保护模式的切换程序 用masm6.14+link 5.12编译出错 “fatal error LNK1190:Invalide fixup found,type 0x0001” masm5.0不支持lgdt命令。

我还有好多问题,如果那位有关于masm详细的资料  麻烦贴出来。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 2368
活跃值: (81)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
2
试试 RadASM
很好的IDE。里面有详细的教程,和例子。及模板...
2008-12-11 14:22
0
雪    币: 214
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
恩  我会到网上找找的
但是 我最急的是当前这个问题。 为什么编译没错 连接不上呢?
2008-12-11 14:28
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
4
连接当然不上了。

16位程序和32位程序的重定位记录(指连接器重定位,不是加载器重定位,即错误报告中的fixup)格式是不一样的。

你的16位代码和32位代码是写在分开的两个段中了吗?
2008-12-11 14:45
0
雪    币: 214
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我编译的这个程序是实模式跳转到保护模式 把110000开始的256字节数据传到buff 然后在跳回实模式下显示 使用了ax同时还使用了eax
  在nasm里 可以用[SECTION .s16]这个来选择是16位的代码还是32位的。在masm下我不知道怎么解决。
2008-12-11 14:54
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
6
首先,你要把32位代码和16位代码定义在不同的段(segment)中,并且声明段的属性,类似这样:
;默认是16位的段
real_seg    segment
;一些16位的代码
;初始化保护模式,并转向保护模式
real_seg    ends

prot_seg    segment use32
;一些32位代码
prot_seg    ends


并且,你使用的连接器必须支持32位程序。

如果进入保护模拟只是为了获得访问32位地址的能力,可以参考一个梁肇新先生在《编程高手箴言》一书中提到的“在DOS下访问4GB内存实用程序”。

只需要给某一个段寄存器(比如FS)赋值为“段基址为0,段限为4G-1”的选择子,之后只要不对它重新赋值,它的值便一直有效。

不过需要一些opcode hack了。

这篇文章可以在谷歌上搜索到,原作者已经不知道了,我是看梁先生的书时知道的这个方法,而且梁先生给出了很详细的讲解。
2008-12-11 16:34
0
雪    币: 442
活跃值: (43)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
王爽里面用的是这两个

编译的时候要留意他生成文件的地址

有可能在C盘的Documents and Settings里面

asm.rar
上传的附件:
2008-12-11 16:45
0
雪    币: 214
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我写了个测试代码(test1.asm)
在masm5.0+link3.6编译通过
assume cs:codesg,ds:datasg
datasg segment
        me db 'hello world!',0dh,0ah,'$'
datasg ends

codesg segment
start:
  mov ax,datasg
        mov ds,ax
        mov ah,09h
        mov dx,offset me
        int 21h

        mov ax,4c00h
        int 21h
codesg ends
end start

masm test1.asm
link3 test1.obj

;---------------------------
但是换成masm6.14或masm6.15+link5.12就编译通不过 信息如下

C:\masm>ml /coff test1.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

Assembling: test1.asm
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

"test1.obj"
"/OUT:test1.exe"
test1.obj : fatal error LNK1190: invalid fixup found, type 0x0001

--------
书呆彭  我的目的不单单是访问4G的内存 我想搞懂实模式 保护模式之间的切换
另外:网上关于这个的保错 中文资料很少
2008-12-11 17:33
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
9
我已经说过了,定义代码段的时候要指定段的属性,汇编器才能生成正确的指令码。如果不指令,它会用默认的属性。

link5.12是32位连接器,你用它来连接16位的代码,当然会出错。

准确地说,你用MASM6汇编,它是按照32位代码段的属性来生成指令的,所以实际上生成的代码与代想生成的代码是不一样的。

在MASM5没有问题是因为它不支持32位,因而生成的代码就是16位的。

在支持32位的MASM6上,你不指定的话,它默认是按照32位来生成的!

你可以试试codeseg segment use16在MASM6上进行汇编。

这些看汇编器的手册就会明白。对于保护模式的初始化,INTEL的手册中有详细的示例代码和讲解。在System Programming Guide一卷中的第9章“Processor management and initialiation”,详细地演示了如何从实模式进入一个flat内存模式的保护模式的代码。

而且示例用的代码就是使用了MASM的语法。

是你不善于挖掘资料罢了。
2008-12-11 19:00
0
雪    币: 196
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
恩,你们都是高手,我尽量理解你们说的话
2008-12-12 01:36
0
游客
登录 | 注册 方可回帖
返回
//