我发现这个GAS文件包含一些可以从CD启动的引导加载程序代码,我想研究它并尝试制作我自己的一个,但唯一的问题是它是AT& T语法没有在英特尔语法中,我对AT& T语法一无所知,我曾尝试使用Intel2gas转换器,但它没有完全转换它,然后我试图转换它不可能的程序,结果是程序结果是一团糟。
以下是intel2gas输出的代码加上我试图解决的问题:
;/* ISO-9660 boot sector
;* --------------------
;*
;* Copyright (c) 2008-2009 Frédéric Feret
;* All rights reserved.
;*
;* Features:
;* - supports ISO-9660 filesystem ("El Torito")
;* - supports multiples burning session
;* - no floppy emulation
;*
;* Limitations:
;* - supports only Joliet format
;*/
BITS 16
ORG 0x00
;/*
; * This is the main function of the boot sector, which loads the OS image
;* into memory at 1000:0000.
;*
;* Parameters:
;* DL = boot disk number.
;*/
;MISMATCH: " .global _start"
_start:
cli
; /* The BIOS has loaded our boot sector at 0000:7C00. We move the code
; of this boot sector at 9000:0000. */
xor ax,ax
mov ds,ax
mov si,07C00h /* DS:SI = 0000:7C00. */
mov ax,09000h
mov es,ax
xor di,di /* ES:DI = 9000:0000. */
mov cx,00800h /* 2048 bytes. */
rep movsb /* do the relocation. */
;/* Jump to the new address. */
;MISMATCH: " ljmp $0x9000, $1f"
;.l1:
; /* Setup segment registers. */
mov ax,cs
mov ds,ax ; /* DS = CS = 9000. */
xor ax,ax
mov es,ax
mov ss,ax ;/* SS = ES = 0000. */
mov sp,07C00h ;/* SS:SP = 0000:7C00. */
; /* Save the boot disk number. */
mov [drive_number],dl
; /* Clear the screen. */
mov ax,003h
int 010h
mov si, msg_loading
call print_string
sti
; /* Check if the processor is a 386. */
pushf
pop ax ; /* FLAGS -> AX */
or ax,03000h ; /* try to set IOPL bits. */
push ax
popf ;/* AX -> FLAGS */
pushf
pop ax ;/* FLAGS -> AX */
test ax,03000h ;/* check if IOPL bits are always set */
jnz short .l1 ;/* it's a 386, or a higher model. */
;/* The processor is a 286 or even older model. We display an error message on the
; screen and then prompts the user to press a key on the keyboard to restart
; the computer. */
mov si, msg_no_386
call print_string
jmp reboot
.l1:
;/* Get the size in bytes of a sector from the BIOS. Normally, the size of
; a sector on a CD-ROM is 2048 bytes. */
mov word [disk_packet],01Ah
mov ah,048h
xor al,al
mov si, disk_packet
mov dl, [drive_number]
int 013h
jc assume_2k_sector
mov ax, disk_packet + 0x18
mov [bytes_per_sect],ax
jmp .l1
assume_2k_sector:
;/* An error occured while retrieving the size of a sector. We will display
; a warning message on the screen, then we assume that a sector on the
; disk makes 2 kilobytes. */
mov word [bytes_per_sect],00800h
mov si, msg_assume_2k_sector
call print_string
.l1:
;/* To load the OS image (which is located at the root directory of the disk),
; we have to look at all sessions of the disk. We will retrieve information
; on the root directory (its size and location) of each session, load the
;directory into memory and see if the OS image filename is in this directory.
;If the file isn't found, we move on to the next session. If all sessions
;were covered and that the filename wasn't found, we conclude that the OS
;image isn't on the disk. The first volume descriptor is the 17th sector of
;the disk. */
mov eax,16
get_next_desc:
;/* Read the sector in memory at 0000:1000. */
mov [desc_sector],eax
mov bx,01000h
mov cx,1
call read_sectors
;/* Check for the signature "\2CD001" at the beginning of the descriptor. */
mov si, cd_signature
mov di,01000h
mov cx,6
cmpsb
je found_desc
;/* Check if we have looked in all the descriptors of volume. */
cmp byte [%es:0x1000],0FFh
jne next_desc
;/* We looked in all sessions of the disk, and the OS image wasn't found.
; We display an error message on the screen and then prompts the user to
; press a key to restart the computer. */
mov si, msg_file_not_found
call print_string
jmp reboot
next_desc:
;/* Compute the next sector number to load. */
mov eax, [desc_sector]
inc eax
jmp get_next_desc
found_desc:
;/* We have to load a volume descriptor of a session in memory. We will check
; if the session supports the Joliet format for storing filenames and
; directories. Otherwise, the session is unknown. */
mov di,01058h
mov si, joliet_signature
mov cx,3
cmps
jne next_desc
;/* We found a session that supports Joliet format. We can find the size and
; the location of the root directory. */
mov eax, [es:0x109E]
mov [root_dir_start],eax
mov eax, [es:0x10A6]
mov [root_dir_size],eax
;/* Compute the number of sectors to load. */
movzx ebx,word [bytes_per_sect]
div ebx
cmp edx,0
je .l1
inc eax
.l1:
mov [root_dir_sectors],ax
;/* Read the root directory in memory at 0000:1000. */
mov eax, [root_dir_start]
mov bx,01000h
mov cx, [root_dir_sectors]
call read_sectors
;/* We will look into the root directory the OS image filename. If the file has
; been found, we save the sector number where that file ans its size in bytes.
; Otherwise, we move to the next session. */
mov di,01000h
search_file:
add di,25
;/* Check if this entry refers to a file. */
cmp byte [es:+di],0
jne next_entry
push di
add di,8
mov si, osimage
mov cx,14
cmps
pop di
je found_file ; /* file found? */
next_entry:
add di,7
movzx ax,byte [%es:+di]
add di,ax
.l1:
inc di
cmp byte [es:+di],0
je 1b
;/* Check if we have check all the entries of the root directory. */
mov eax, [root_dir_size]
add eax,01000h
cmp di,ax
jb search_file
;/* The OS image wasn't found in the root directory. We go to the next
; session of the disk. */
jmp next_desc
found_file:
sub di,25
;/* Get the location of this file. */
mov eax, [es:2+di]
mov [file_start],eax
;/* Get the size of this file. */
mov eax, [es:10+di]
mov [file_size],eax
/* Compute the number of sectors to load. */
movzx ebx,word [bytes_per_sect]
div ebx
cmp edx,0
je .l1
inc eax
.l1:
mov [file_sectors],ax
;/* Read the OS image in memory at 1000:0000. */
mov eax, [file_start]
mov bx,01000h
mov es,bx
xor bx,bx
mov cx, [file_sectors]
call read_sectors
mov dl, [drive_number]
xor si,si
;/* Run the OS loader... */
ljmp 0x1000:0x0000
;/*
; * This function loads one or more sectors in memory.
; *
; * Parmaeters:
; * EAX first sector to load.
; * CX number of sectors to load.
; * ES:BX destination address.
; */
read_sectors:
; /* To request the BIOS to load the sectors, we need to build a data
; packet that contains the number or sectors to load, the first
; logical sector to load and destination address. The address of
; this packet will then be given to the BIOS, which loads these
; sectors into memory. */
mov byte [disk_packet],010h
; /* We don't read one single sector at a time. */
mov disk_packet + 2, 0x01
; /* Write the destination address. */
mov disk_packet + 4, bx
mov disk_packet + 6, es
;/* Write the logical sector to load. */
mov disk_packet + 8, eax
mov disk_packet + 12, 0x0
read_one_sector:
;/* Read the sector into memory. */
mov ah,042h
xor al,al
mov si, disk_packet
mov dl, [drive_number]
int 013h;
jnc short .l1 /* read error? */
mov si, msg_read_error
call print_string
jmp reboot
.l1:
; /* Updates the next sector to load. */
inc disk_packet + 8
; /* Updates the destination address. Rather than incrementing the offset, we
; will increase the segment. */
mov ax, [bytes_per_sect]
shr ax,4
add disk_packet + 6, ax
loop read_one_sector
ret
;/*
;* This function displays a string to the screen, at the current cursor
;* position.
;*
;* Parameters:
;* DS:SI null-terminated string.
;*/
print_string:
; /* Read a character. */
repe lodsb
; /* Check if we reached the end of the string. */
cmp al,0
je short .l1
; /* Displays the character on screen. */
mov ah,00Eh
mov bx,007h
int 010h
jmp print_string
.l1:
ret
;/*
; * This function reboots the computer.
; */
reboot:
mov si, msg_reboot
call print_string
; /* Wait for a key. */
xor ax,ax
int 016h
; /* Rebooting... */
int 019h
;/*
; * Messages
; */
msg_loading: db '\n\rLoading...\n\n\r', 0
msg_no_386: db 'Error: 386 or higher processor required.\n\r', 0
msg_assume_2k_sector: db 'Error: failed to get sector size, assume 2 Kb.\n\r', 0
msg_file_not_found: db 'Error: OS image not found.\n\r', 0
msg_read_error: db 'Error: cannot read on disk.\n\r', 0
msg_reboot: db 'Press any key to restart your computer.\n\r', 0
;/*
; * Datas
; */
cd_signature: db 002h
db 'CD001'
joliet_signature: db 025h,02Fh,045h
MISMATCH: "osimage: .byte 0, 'o', 0, 's', 0, 'i', 0, 'm', 0, 'a', 0, 'g', 0, 'e'"
drive_number: db 0
bytes_per_sect: dw 0
root_dir_size: dd 0
root_dir_sectors: dw 0
root_dir_start: dd 0
file_size: dd 0
file_sectors: dw 0
file_start: dd 0
desc_sector: dd 0
disk_packet: RESB 020h
;/*
;* Boot sector signature
;*/
ORG 2046
dw 0AA55h
以下是我尝试组装时给我的所有错误
cdfs2.asm:34: error: expression syntax error
cdfs2.asm:37: error: expression syntax error
cdfs2.asm:38: error: expression syntax error
cdfs2.asm:39: error: expression syntax error
cdfs2.asm:47: error: expression syntax error
cdfs2.asm:50: error: expression syntax error
cdfs2.asm:51: error: expression syntax error
cdfs2.asm:67: error: expression syntax error
cdfs2.asm:68: error: expression syntax error
cdfs2.asm:70: error: expression syntax error
cdfs2.asm:73: error: expression syntax error
cdfs2.asm:74: error: expression syntax error
cdfs2.asm:75: error: expression syntax error
cdfs2.asm:133: error: expression syntax error
cdfs2.asm:197: error: symbol `cmps' redefined
cdfs2.asm:203: error: expression syntax error
cdfs2.asm:232: error: label or instruction expected at start of line
cdfs2.asm:253: error: parser: instruction expected
cdfs2.asm:289: error: expression syntax error
cdfs2.asm:363: error: parser: instruction expected
cdfs2.asm:378: error: program origin redefined
这就是我用来组装的东西
nasm cdfs2.asm -o CD.iso
我已修复它所以它现在已经组装但它现在给我一个错误当我尝试将ISO加载到虚拟框中时不支持该格式我的猜测是因为程序员在上面所说的那个
;* Limitations:
;* - supports only Joliet format
有没有解决这个问题?这是转换后的代码:
;/* ISO-9660 boot sector
;* --------------------
;*
;* Copyright (c) 2008-2009 Frédéric Feret
;* All rights reserved.
;*
;* Features:
;* - supports ISO-9660 filesystem ("El Torito")
;* - supports multiples burning session
;* - no floppy emulation
;*
;* Limitations:
;* - supports only Joliet format
;*/
BITS 16
ORG 0x00
;/*
; * This is the main function of the boot sector, which loads the OS image
;* into memory at 1000:0000.
;*
;* Parameters:
;* DL = boot disk number.
;*/
;MISMATCH: " .global _start"
;_start:
cli
; /* The BIOS has loaded our boot sector at 0000:7C00. We move the code
; of this boot sector at 9000:0000. */
xor ax,ax
mov ds,ax
mov si,07C00h ; /* DS:SI = 0000:7C00. */
mov ax,09000h
mov es,ax
xor di,di ; /* ES:DI = 9000:0000. */
mov cx,00800h ; /* 2048 bytes. */
rep movsb ; /* do the relocation. */
;/* Jump to the new address. */
;MISMATCH: " ljmp $0x9000, $1f"
jmp 0x9000:here
here:
; /* Setup segment registers. */
mov ax,cs
mov ds,ax ; /* DS = CS = 9000. */
xor ax,ax
mov es,ax
mov ss,ax ;/* SS = ES = 0000. */
mov sp,07C00h ;/* SS:SP = 0000:7C00. */
; /* Save the boot disk number. */
mov [drive_number],dl
; /* Clear the screen. */
mov ax,003h
int 010h
mov si, msg_loading
call print_string
sti
; /* Check if the processor is a 386. */
pushf
pop ax ; /* FLAGS -> AX */
or ax,03000h ; /* try to set IOPL bits. */
push ax
popf ;/* AX -> FLAGS */
pushf
pop ax ;/* FLAGS -> AX */
test ax,03000h ;/* check if IOPL bits are always set */
jnz short .l1 ;/* it's a 386, or a higher model. */
;/* The processor is a 286 or even older model. We display an error message on the
; screen and then prompts the user to press a key on the keyboard to restart
; the computer. */
mov si, msg_no_386
call print_string
jmp reboot
.l1:
;/* Get the size in bytes of a sector from the BIOS. Normally, the size of
; a sector on a CD-ROM is 2048 bytes. */
mov word [disk_packet],01Ah
mov ah,048h
xor al,al
mov si, disk_packet
mov dl, [drive_number]
int 013h
jc assume_2k_sector
mov ax, disk_packet + 0x18
mov [bytes_per_sect],ax
jmp .l1
assume_2k_sector:
;/* An error occured while retrieving the size of a sector. We will display
; a warning message on the screen, then we assume that a sector on the
; disk makes 2 kilobytes. */
mov word [bytes_per_sect],00800h
mov si, msg_assume_2k_sector
call print_string
.l1:
;/* To load the OS image (which is located at the root directory of the disk),
; we have to look at all sessions of the disk. We will retrieve information
; on the root directory (its size and location) of each session, load the
;directory into memory and see if the OS image filename is in this directory.
;If the file isn't found, we move on to the next session. If all sessions
;were covered and that the filename wasn't found, we conclude that the OS
;image isn't on the disk. The first volume descriptor is the 17th sector of
;the disk. */
mov eax,16
get_next_desc:
;/* Read the sector in memory at 0000:1000. */
mov [desc_sector],eax
mov bx,01000h
mov cx,1
call read_sectors
;/* Check for the signature "\2CD001" at the beginning of the descriptor. */
mov si, cd_signature
mov di,01000h
mov cx,6
cmpsb
je found_desc
;/* Check if we have looked in all the descriptors of volume. */
cmp byte [es:0x1000],0FFh
jne next_desc
;/* We looked in all sessions of the disk, and the OS image wasn't found.
; We display an error message on the screen and then prompts the user to
; press a key to restart the computer. */
mov si, msg_file_not_found
call print_string
jmp reboot
next_desc:
;/* Compute the next sector number to load. */
mov eax, [desc_sector]
inc eax
jmp get_next_desc
found_desc:
;/* We have to load a volume descriptor of a session in memory. We will check
; if the session supports the Joliet format for storing filenames and
; directories. Otherwise, the session is unknown. */
mov di,01058h
mov si, joliet_signature
mov cx,3
cmpsb
jne next_desc
;/* We found a session that supports Joliet format. We can find the size and
; the location of the root directory. */
mov eax, [es:0x109E]
mov [root_dir_start],eax
mov eax, [es:0x10A6]
mov [root_dir_size],eax
;/* Compute the number of sectors to load. */
movzx ebx,word [bytes_per_sect]
div ebx
cmp edx,0
je .l1
inc eax
.l1:
mov [root_dir_sectors],ax
;/* Read the root directory in memory at 0000:1000. */
mov eax, [root_dir_start]
mov bx,01000h
mov cx, [root_dir_sectors]
call read_sectors
;/* We will look into the root directory the OS image filename. If the file has
; been found, we save the sector number where that file ans its size in bytes.
; Otherwise, we move to the next session. */
mov di,01000h
search_file:
add di,25
;/* Check if this entry refers to a file. */
cmp byte [es:+di],0
jne next_entry
push di
add di,8
mov si, osimage
mov cx,14
cmpsb
pop di
je found_file ; /* file found? */
next_entry:
add di,7
movzx ax,byte [es:+di]
add di,ax
.l1:
inc di
cmp byte [es:+di],0
je 1b
;/* Check if we have check all the entries of the root directory. */
mov eax, [root_dir_size]
add eax,01000h
cmp di,ax
jb search_file
;/* The OS image wasn't found in the root directory. We go to the next
; session of the disk. */
jmp next_desc
found_file:
sub di,25
;/* Get the location of this file. */
mov eax, [es:2+di]
mov [file_start],eax
;/* Get the size of this file. */
mov eax, [es:10+di]
mov [file_size],eax
;/* Compute the number of sectors to load. */
movzx ebx,word [bytes_per_sect]
div ebx
cmp edx,0
je .l1
inc eax
.l1:
mov [file_sectors],ax
;/* Read the OS image in memory at 1000:0000. */
mov eax, [file_start]
mov bx,01000h
mov es,bx
xor bx,bx
mov cx, [file_sectors]
call read_sectors
mov dl, [drive_number]
xor si,si
;/* Run the OS loader... */
jmp 0x1000:0x0000
;/*
; * This function loads one or more sectors in memory.
; *
; * Parmaeters:
; * EAX first sector to load.
; * CX number of sectors to load.
; * ES:BX destination address.
; */
read_sectors:
; /* To request the BIOS to load the sectors, we need to build a data
; packet that contains the number or sectors to load, the first
; logical sector to load and destination address. The address of
; this packet will then be given to the BIOS, which loads these
; sectors into memory. */
mov byte [disk_packet],010h
; /* We don't read one single sector at a time. */
mov [disk_packet + 2], word 0x01
; /* Write the destination address. */
mov [disk_packet + 4], bx
mov [disk_packet + 6], es
;/* Write the logical sector to load. */
mov [disk_packet + 8], eax
mov [disk_packet + 12], dword 0x0
read_one_sector:
;/* Read the sector into memory. */
mov ah,042h
xor al,al
mov si, disk_packet
mov dl, [drive_number]
int 013h
jnc short .l1 ; /* read error? */
mov si, msg_read_error
call print_string
jmp reboot
.l1:
; /* Updates the next sector to load. */
inc dword [disk_packet + 8]
; /* Updates the destination address. Rather than incrementing the offset, we
; will increase the segment. */
mov ax, [bytes_per_sect]
shr ax,4
add [disk_packet + 6], ax
loop read_one_sector
ret
;/*
;* This function displays a string to the screen, at the current cursor
;* position.
;*
;* Parameters:
;* DS:SI null-terminated string.
;*/
print_string:
; /* Read a character. */
repe lodsb
; /* Check if we reached the end of the string. */
cmp al,0
je short .l1
; /* Displays the character on screen. */
mov ah,00Eh
mov bx,007h
int 010h
jmp print_string
.l1:
ret
;/*
; * This function reboots the computer.
; */
reboot:
mov si, msg_reboot
call print_string
; /* Wait for a key. */
xor ax,ax
int 016h
; /* Rebooting... */
int 019h
;/*
; * Messages
; */
msg_loading: db `\n\rLoading...\n\n\r`, 0
msg_no_386: db `Error: 386 or higher processor required.\n\r`, 0
msg_assume_2k_sector: db `Error: failed to get sector size, assume 2 Kb.\n\r`, 0
msg_file_not_found: db `Error: OS image not found.\n\r`, 0
msg_read_error: db `Error: cannot read on disk.\n\r`, 0
msg_reboot: db `Press any key to restart your computer.\n\r`, 0
;/*
; * Datas
; */
cd_signature: db 002h
db 'CD001'
joliet_signature: db 025h,02Fh,045h
osimage: db 0, 'o', 0, 's', 0, 'i', 0, 'm', 0, 'a', 0, 'g', 0, 'e'
drive_number: db 0
bytes_per_sect: dw 0
root_dir_size: dd 0
root_dir_sectors: dw 0
root_dir_start: dd 0
file_size: dd 0
file_sectors: dw 0
file_start: dd 0
desc_sector: dd 0
disk_packet: times 020h db 0
;/*
;* Boot sector signature
;*/
; ORG 2046
times 2046 - ($ - $$) db 0
dw 0AA55h
答案 0 :(得分:6)
唯一的问题是它采用AT& T语法而不是英特尔语法,而且我对AT& T语法一无所知
假设您对英特尔语法x86汇编有一个很好的把握,这里简要总结了AT& T语法中最重要的差异(取自here):
注册命名
注册名称以%
为前缀。也就是说,如果必须使用eax
,则应将其用作%eax
。
来源和目的地排序
在任何指令中,源首先出现,目的地紧随其后。这与英特尔语法不同,其中source来自目的地。
mov %eax, %ebx
,将eax
的内容转移到ebx
。
操作数的大小
说明的后缀为b
,w
或l
,具体取决于操作数是字节,字还是长。这不是强制性的; GCC尝试通过读取操作数来提供适当的后缀。但是手动指定后缀可以提高代码的可读性,并消除编译器错误猜测的可能性。
movb %al, %bl -- Byte move
movw %ax, %bx -- Word move
movl %eax, %ebx -- Longword move
立即操作数
使用$
指定立即操作数。
movl $0xffff, %eax -- will move the value of 0xffff into eax register.
间接记忆参考
使用( )
完成对内存的任何间接引用。
movb (%esi), %al -- will transfer the byte in the memory
pointed by esi into al register
答案 1 :(得分:0)
由于您提供的转换文件包含错误消息,我们可以提供帮助。
cdfs2.asm:232:错误:行开头预期的标签或指令
看来这个角色;如果您想使用评论,则是必需的。这里缺少这个!
cdfs2.asm:253:错误:解析器:预期指令
没有ljmp
助记符,请查看Intel instruction set reference manual。无条件跳转的助记符为jmp
。
cdfs2.asm:363:错误:解析器:预期指令
字符串应以<{1}}开头,如
db
cdfs2.asm:378:错误:程序原点重新定义
似乎不允许使用“ORG”重新定义原点。
cdfs2.asm:197:错误:符号`cmps'重新定义
不允许使用隐式表单,
MISMATCH: db 'osimage:', 0, 'o', 0, 's', 0, 'i', 0, 'm', 0, 'a', 0, 'g', 0, 'e'
cdfs2.asm:203:错误:表达式语法错误
Cpu寄存器ES,DS,AX,BX,CX,DX ......没有AT&amp; T语法中的%前缀。
cdfs2.asm:34:错误:表达式语法错误
cdfs2.asm:37:错误:表达式语法错误
cdfs2.asm:38:错误:表达式语法错误
cdfs2.asm:39:错误:表达式语法错误
评论应以CMPS ES:[DI]
字符
这些信息可能有助于检测类似的错误。