Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
没有windows api的NASM中的hello world_Windows_Assembly_Nasm_Masm - Fatal编程技术网

没有windows api的NASM中的hello world

没有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库,如

我一直在使用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。我想赤裸裸地做这件事。下面是一个小插曲:

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