1: Near 近端使用
C语言实现:
#include <stdio.h>
#include <stdlib.h>
void print(){
printf("proc");
}
int main(int argc, char *argv[]) {
print();
return 0;
}
汇编实现:
datas segment
x db 'proc$';
datas ends
stacks segment stack
dw 100 dup(?)
stacks ends
codes segment
assume cs:codes,ss:stacks,ds:datas
main proc ; 主程序
start:
mov ax,datas;
mov ds,ax;
call max
mov ah,4ch;
int 21h
main endp
print proc near ;子程序
push bp;
mov bp,sp;
mov dx,offset x;
mov ah,09;
int 21h
pop bp
ret 0
print endp
codes ends
end start

near 调用没有段地址:使用的就是偏移地址 call 000C 地址就是子程序的入口地址
2: Far 远端使用
print 函数我们实现在另一个文件, C语言默认函数的extern的 也就是全局的
// A文件
#include<stdio.h>
void print(){
printf("proc");
}
// 主调用文件
#include <stdio.h>
#include <stdlib.h>
extern void print();
int main(int argc, char *argv[]) {
print();
return 0;
}
汇编实现:
;A文件public printx '声明为远端函数
datas segment
x db 'proc$';
datas ends
assume cs:codes,ds:datas
codes segment
print proc far
push dx
push ax
push bp;
mov bp,sp;
mov ax,datas;这里我们直接在本段进行处理 ,如果不在本段处理 需要将main的段内存的偏低地址,push 到堆栈中操作内容
mov ds,ax
mov dx,offset x;取得偏移地址
mov ah,09;
int 21h;
pop dx
pop ax
pop bp
retf
print endp
codes ends
end
;Main 文件
stacks segment stack
dw 100 dup(0)
stacks ends;
extrn printx:far ;标识远端程序 不写 将会汇编错误 ,
codes segment
assume cs:codes,ss:stacks
main proc
start:
call far ptr printx
mov ah,4ch
int 21h;
hlt
main endp
codes ends
end start
注意: 以上两个文件编译没有问题,但是链接 如果按照我们过去的思路 将会出现下面的错误: 表示我们调用的函数需要声明 否则无法链接

注意: 调用了多少个far子程序 那么链接时候需要
link main.obj+pro1.obj+pro2.obj+''' 依次类推
debug:
主程序为: 调用地址 0779:0000

看一下调用地址的子程序地址:

3:Far使用过程的问题
如果声明为跨段调用,因为段限制为64k, 需要使用call far ptr进行调用
下面的声明形式是错误的:
stacks segment stack
dw 100 dup(0)
stacks ends;
extrn printx:far
codes segment
assume cs:codes,ss:stacks
start:
call far ptr printx
mov ah,4ch
int 21h;
hlt
codes ends
end start
正确的声明形式:
stacks segment stack
dw 100 dup(0)
stacks ends;
extrn printx:far
codes segment
assume cs:codes,ss:stacks
main proc ; 主程序也必须声明为 过程 这里 near调用还是有很大的区别的
start:
call far ptr printx
mov ah,4ch
int 21h;
hlt
main endp
codes ends
end start
4: 参数传递的问题:
4.1 寄存器传递参数
datas segment
x db 'proc$';
datas ends
stacks segment stack
dw 100 dup(?)
stacks ends
codes segment
assume cs:codes,ss:stacks,ds:datas
main proc ; 主程序
start:
mov ax,datas;
mov ds,ax;
mov dx,offset x; 直接使用 传递给寄存器dx
call far ptr print
mov ah,4ch;
int 21h
main endp
print proc
mov ah,09; 使用寄存器dx
int 21h
retf
print endp
codes ends
end start
4.2 内存传递参数
datas segment
x db 'proc$';
datas ends
stacks segment stack
dw 100 dup(?)
stacks ends
codes segment
assume cs:codes,ss:stacks,ds:datas
main proc ; 主程序
start:
mov ax,datas;
mov ds,ax;
call far ptr print
mov ah,4ch;
int 21h
main endp
print proc
mov dx,offset x; 取得数据段首地址
mov ah,09; 输出dx的数据值
int 21h
retf
print endp
codes ends
end start
4.3 内存传递参数的改进(栈恢复)
如果用到ax bx cx dx si di 需要进行恢复
datas segment
x db 'proc$';
datas ends
stacks segment stack
dw 100 dup(?)
stacks ends
codes segment
assume cs:codes,ss:stacks,ds:datas
main proc ; 主程序
start:
mov ax,stacks;初始化栈
mov ss,ax;
mov ax,datas;初始数据段
mov ds,ax;
xor ax,ax
mov ax,offset x;
push ax;ax偏移地址入栈
call print
mov ah,4ch;
int 21h
main endp
print proc
push bp;
mov bp,sp
mov dx,[bp+4];寻地址
mov ah,09;
int 21h
pop bp
ret 2;保持恢复
print endp
codes ends
end start