没有windows api的NASM中的hello world
我一直在使用NASM在Linux上汇编代码,现在正在尝试学习Windows上的汇编代码。继Ray Duncan的高级MS-DOS编程之后,图3-7列出了一个基于MASM的hello world程序,该程序基本上使用中断21h打印“hello world”。这与在Linux上使用中断80h做同样的事情是同义的,感觉就像在家一样。我想在windows上使用NASM做同样的事情 网络上的大多数示例都使用Windows API,如_GetStdHandle、_writeconolea等,或者使用C库,如_printf。我想赤裸裸地做这件事。下面是一个小插曲:没有windows api的NASM中的hello world,windows,assembly,nasm,masm,Windows,Assembly,Nasm,Masm,我一直在使用NASM在Linux上汇编代码,现在正在尝试学习Windows上的汇编代码。继Ray Duncan的高级MS-DOS编程之后,图3-7列出了一个基于MASM的hello world程序,该程序基本上使用中断21h打印“hello world”。这与在Linux上使用中断80h做同样的事情是同义的,感觉就像在家一样。我想在windows上使用NASM做同样的事情 网络上的大多数示例都使用Windows API,如_GetStdHandle、_writeconolea等,或者使用C库,如
global _start
section .data
str: db 'hello, world',0xA
strLen: equ $-str
section .text
_start:
mov ah,40h
mov bx,1
mov cx, strLen
mov dx, str
int 21h
mov ax,4c00h
int 21h
希望我没有模棱两可:)如果DOS功能不够简单,您可以使用电脑固件中硬连线的BIOS功能。它们记录在Ralf Brown的中断列表中
我喜欢从vitsoft中选择上面代码的一些变体,而不使用软件中断将字符串直接打印到给定的屏幕坐标,我们必须在下面的代码中指定。(但它不会触摸或移动屏幕或位置。)对于64位窗口,请使用DOSBOX
; Save as hello.asm, assemble with nasm -f bin -o hello.com hello.asm
ORG 256
Start: JMP Main
strOfs DB 'hello, world'
strLen EQU $-strOfs ; meaning of $ = offset address of this position in the code
Main: MOV SI,strOfs ; offset address of the string
MOV CX,strLen ; lenght of the string
MOV AX, 0B800h ; segment address of the textmode video buffer
MOV ES, AX ; store the address in the extra segment register
MOV DI, (Line_Number*80*2)+(Row_number*2) ; target address on the screen
CLD ; let the pointer adjustment step forward for string instructions
nextChar: LODSB ; load AL from DS:[SI], increment SI
STOSB ; store AL into ES:[DI], increment DI
INC DI ; step over attribute byte
LOOP nextChar ; repeat until CX=0
MOV AH,00h ; BIOS function GET KEYSTROKE
INT 16h ; Press any key to continue
RET ; Exit program
中断21h是DOS调用,因此将在DOS下运行。我建议你打开一个DOS窗口,然后从那里运行你的程序,以便查看输出。32位Windows系统将运行一个16位DOS程序,因此如果适合的话,你可以使用Ray Duncan版本。但是,64位Windows系统不再具有MS-DOS子系统/仿真,因此无法在那里工作。您将需要使用Windows API,或者如果您更喜欢使用原生NT API(它们非常相似,但通常没有文档记录)。如果您想使用实际的系统功能分派器,请参阅Russinovich的“Windows内部”一书-实际使用的系统分派机制非常依赖于处理器和Windows版本。中断由操作系统处理,而不是由固件处理。@Praxelitic当然,但只有在操作系统负责时才是如此。在启动之前,BIOS将中断表初始化为指向自己的例程,以便在启动过程中使用它们。即使在加载Windows时,它也会模拟BIOS中断的大多数功能。这就是为什么上面的代码可以在引导扇区代码、DOS和32位Windows中工作。
; Save as hello.asm, assemble with nasm -f bin -o hello.com hello.asm
ORG 256
Start: JMP Main
strOfs DB 'hello, world'
strLen EQU $-strOfs ; meaning of $ = offset address of this position in the code
Main: MOV SI,strOfs ; offset address of the string
MOV CX,strLen ; lenght of the string
MOV AX, 0B800h ; segment address of the textmode video buffer
MOV ES, AX ; store the address in the extra segment register
MOV DI, (Line_Number*80*2)+(Row_number*2) ; target address on the screen
CLD ; let the pointer adjustment step forward for string instructions
nextChar: LODSB ; load AL from DS:[SI], increment SI
STOSB ; store AL into ES:[DI], increment DI
INC DI ; step over attribute byte
LOOP nextChar ; repeat until CX=0
MOV AH,00h ; BIOS function GET KEYSTROKE
INT 16h ; Press any key to continue
RET ; Exit program