#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2014
    Posts
    1
    Rep Power
    0

    Translating AT&T syntax to INTEL Syntax


    I have been trying to find a simple bootloader that could boot off of a CD and then I did find one but it was written in AT&T Syntax and I only know Intel I have tried using intel2gas but that didn't work out so good. Could anyone point me in the right direction so I can try and translate this Assembly code to Intel Syntax (I use NASM By The Way).
    Here is the code:
    Code:
    /* 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
     */
    	.text
    	.code16
    
    	.org 0
    
    /*
     * This is the main function of the boot sector, which loads the OS image
     * into memory at 1000:0000.
     *
     * Parameters:
     *	DL = boot disk number.
     */
    	.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. */
    	xorw	%ax, %ax
    	movw	%ax, %ds
    	movw	$0x7C00, %si				/* DS:SI = 0000:7C00. */
    	movw	$0x9000, %ax
    	movw	%ax, %es
    	xorw	%di, %di				/* ES:DI = 9000:0000. */
    	movw	$0x0800, %cx				/* 2048 bytes. */
    	rep
    	movsb						/* do the relocation. */
    
    	/* Jump to the new address. */
    	ljmp	$0x9000, $1f
    
    1:
    	/* Setup segment registers. */
    	movw	%cs, %ax
    	movw	%ax, %ds				/* DS = CS = 9000. */
    	xorw	%ax, %ax
    	movw	%ax, %es
    	movw	%ax, %ss				/* SS = ES = 0000. */
    	movw	$0x7C00, %sp				/* SS:SP = 0000:7C00. */
    
    	/* Save the boot disk number. */
    	movb	%dl, drive_number
    
    	/* Clear the screen. */
    	movw	$0x03, %ax
    	int	$0x10
    
    	movw	$msg_loading, %si
    	call	print_string
    
    	sti
    
    	/* Check if the processor is a 386. */
    	pushf
    	popw	%ax					/* FLAGS -> AX */
    	orw	$0x3000, %ax				/* try to set IOPL bits. */
    	pushw	%ax
    	popf						/* AX -> FLAGS */
    
    	pushf
    	popw	%ax					/* FLAGS -> AX */
    	testw	$0x3000, %ax				/* check if IOPL bits are always set */
    	jnz	1f					/* 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. */
    	movw	$msg_no_386, %si
    	call	print_string
    	jmp	reboot
    
    1:
    	/* Get the size in bytes of a sector from the BIOS. Normally, the size of
    	   a sector on a CD-ROM is 2048 bytes. */
    	movw	$0x1A, disk_packet
    	movb	$0x48, %ah
    	xorb	%al, %al
    	movw	$disk_packet, %si
    	movb	drive_number, %dl
    	int	$0x13
    	jc	assume_2k_sector
    
    	movw	disk_packet + 0x18, %ax
    	movw	%ax, bytes_per_sect
    	jmp	1f
    
    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. */
    	movw	$0x0800, bytes_per_sect
    	movw	$msg_assume_2k_sector, %si
    	call	print_string
    
    1:
    	/* 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. */
    	movl	$16, %eax
    
    get_next_desc:
    	/* Read the sector in memory at 0000:1000. */
    	movl	%eax, desc_sector
    	movw	$0x1000, %bx
    	movw	$1, %cx
    	call	read_sectors
    
    	/* Check for the signature "\2CD001" at the beginning of the descriptor. */
    	movw	$cd_signature, %si
    	movw	$0x1000, %di
    	movw	$6, %cx
    	repe
    	cmpsb
    	je	found_desc
    
    	/* Check if we have looked in all the descriptors of volume. */
    	cmpb	$0xFF, %es:0x1000
    	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. */
    	movw	$msg_file_not_found, %si
    	call	print_string
    	jmp	reboot
    
    next_desc:
    	/* Compute the next sector number to load. */
    	movl	desc_sector, %eax
    	incl	%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. */
    	movw	$0x1058, %di
    	movw	$joliet_signature, %si
    	movw	$3, %cx
    	repe
    	cmpsb
    	jne	next_desc
    
    	/* We found a session that supports Joliet format. We can find the size and
    	   the location of the root directory. */
    	movl	%es:0x109E, %eax
    	movl	%eax, root_dir_start
    	movl	%es:0x10A6, %eax
    	movl	%eax, root_dir_size
    
    	/* Compute the number of sectors to load. */
    	movzwl	bytes_per_sect, %ebx
    	divl	%ebx
    	cmpl	$0, %edx
    	je	1f
    	incl	%eax
    1:
    	movw	%ax, root_dir_sectors
    
    	/* Read the root directory in memory at 0000:1000. */
    	movl	root_dir_start, %eax
    	movw	$0x1000, %bx
    	movw	root_dir_sectors, %cx
    	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. */
    	movw	$0x1000, %di
    
    search_file:
    	addw	$25, %di
    
    	/* Check if this entry refers to a file. */
    	cmpb	$0, %es:(%di)
    	jne	next_entry
    
    	pushw	%di
    	addw	$8, %di
    	movw	$osimage, %si
    	movw	$14, %cx
    	repe
    	cmpsb
    	popw	%di
    	je	found_file				/* file found? */
    
    next_entry:
    	addw	$7, %di
    	movzbw	%es:(%di), %ax
    	addw	%ax, %di
    
    1:
    	incw	%di
    	cmpb	$0, %es:(%di)
    	je	1b
    
    	/* Check if we have check all the entries of the root directory. */
    	movl	root_dir_size, %eax
    	addl	$0x1000, %eax
    	cmpw	%ax, %di
    	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:
    	subw	$25, %di
    
    	/* Get the location of this file. */
    	movl	%es:2(%di), %eax
    	movl	%eax, file_start
    
    	/* Get the size of this file. */
    	movl	%es:10(%di), %eax
    	movl	%eax, file_size
    
    	/* Compute the number of sectors to load. */
    	movzwl	bytes_per_sect, %ebx
    	divl	%ebx
    	cmpl	$0, %edx
    	je	1f
    	incl	%eax
    1:
    	movw	%ax, file_sectors
    
    	/* Read the OS image in memory at 1000:0000. */
    	movl	file_start, %eax
    	movw	$0x1000, %bx
    	movw	%bx, %es
    	xorw	%bx, %bx
    	movw	file_sectors, %cx
    	call	read_sectors
    
    	movb	drive_number, %dl
    	xorw	%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. */
    	movb	$0x10, disk_packet
    
    	/* We don't read one single sector at a time. */
    	movw	$1, disk_packet + 2
    
    	/* Write the destination address. */
    	movw	%bx, disk_packet + 4
    	movw	%es, disk_packet + 6
    
    	/* Write the logical sector to load. */
    	movl	%eax, disk_packet + 8
    	movl	$0, disk_packet + 12
    
    read_one_sector:
    	/* Read the sector into memory. */
    	movb	$0x42, %ah
    	xorb	%al, %al
    	movw	$disk_packet, %si
    	movb	drive_number, %dl
    	int	$0x13
    	jnc	1f					/* read error? */
    
    	movw	$msg_read_error, %si
    	call	print_string
    	jmp	reboot
    
    1:
    	/* Updates the next sector to load. */
    	incl	disk_packet + 8
    
    	/* Updates the destination address. Rather than incrementing the offset, we
    	   will increase the segment. */
    	movw	bytes_per_sect, %ax
    	shrw	$4, %ax
    	addw	%ax, disk_packet + 6
    	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. */
    	lodsb
    
    	/* Check if we reached the end of the string. */
    	cmpb	$0, %al
    	je	1f
    
    	/* Displays the character on screen. */
    	movb	$0x0E, %ah
    	movw	$0x07, %bx
    	int	$0x10
    
    	jmp	print_string
    
    1:
    	ret
    
    /*
     * This function reboots the computer.
     */
    reboot:
    	movw	$msg_reboot, %si
    	call	print_string
    
    	/* Wait for a key. */
    	xorw	%ax, %ax
    	int	$0x16
    
    	/* Rebooting... */
    	int	$0x19
    
    /*
     * Messages
     */
    msg_loading:		.asciz "\n\rLoading...\n\n\r"
    msg_no_386:		.asciz "Error: 386 or higher processor required.\n\r"
    msg_assume_2k_sector:	.asciz "Error: failed to get sector size, assume 2 Kb.\n\r"
    msg_file_not_found:	.asciz "Error: OS image not found.\n\r"
    msg_read_error:		.asciz "Error: cannot read on disk.\n\r"
    msg_reboot:		.asciz "Press any key to restart your computer.\n\r"
    
    /*
     * Datas
     */
    cd_signature:		.byte 0x02
    			.ascii "CD001"
    joliet_signature:	.byte 0x25, 0x2F, 0x45
    osimage:		.byte 0, 'o', 0, 's', 0, 'i', 0, 'm', 0, 'a', 0, 'g', 0, 'e'
    drive_number:		.byte 0
    bytes_per_sect:		.word 0
    root_dir_size:		.long 0
    root_dir_sectors:	.word 0
    root_dir_start:		.long 0
    file_size:		.long 0
    file_sectors:		.word 0
    file_start:		.long 0
    desc_sector:		.long 0
    disk_packet:		.space 0x20
    
    /*
     * Boot sector signature
     */
    	.org 2046
    	.word 0xAA55
  2. #2
  3. Commie Mutant Traitor
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Jun 2004
    Location
    Alpharetta, GA
    Posts
    1,809
    Rep Power
    1573
    My best suggestion is to read the explanation of the differences between the two syntaces on the OSDev wiki. It covers the main points of how they differ, and what needs to be done to convert one to the other by hand.

    I will give the following advice, though:
    • Registers are prefixed with a percent sign (%). Simply doing a search-replace to remove the percent signs will do about a quarter of the work for you by itself.
    • Similarly, immediate values are prefixed with a dollar sign. These can be removed the same way as the percent signs.
    • AT&T syntax adds a word size to any instruction that involves moving or computing values. Thus, movb is 'move byte', movw is 'move word', movl is 'move long' (ie, 32 bit), and so forth. In most cases, these affix markers can be simply ignored, as the operand size will be apparent from the operands; in cases where it isn't, you would add a size marker before the operand; e.g., MOV AH, BYTE 2h.
    • Most of the binary instructions (move, add, and so forth) are reversed in AT&T syntax from the Intel style; for example, movw %ax, %bx moves from AX to BX, whereas in Intel syntax this would be MOV BX, AX (that is, destination first, source second). Unfortunately, there's no simple bulk replace that will fix this without multiple passes.
    • The really tricky issue is dealing with indirection. In AT&T syntax, a base register is given with parentheses, and the index values are put directly in front of the base. For example, movl %es:10(%di), %eax moves a doubleword address in the ES segment held in EDI, with an offset of 10, to EAX. In Intel syntax, this would become MOV EAX, DWORD [ESI + 10]. Which of these approaches is uglier is a matter of opinion.


    The rest you should be able to get from the page I linked, but these should be enough for most of the changes needed.
    Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
    #define KINSEY (rand() % 7) λ Scheme is the Red Pill
    Scheme in ShortUnderstanding the C/C++ Preprocessor
    Taming PythonA Highly Opinionated Review of Programming Languages for the Novice, v1.1

    FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2015
    Location
    Colorado Springs, CO
    Posts
    20
    Rep Power
    0
    Compile using gas then use ndisasm to extract intel syntax.

    If youre doing OS Dev though (which it looks like you are), you will probably need to have some familiarity with AT&T syntax for stuff in your kernel, GDT/IDT, interrupts, IO, paging, or when you get to writing your libc, system calls.

IMN logo majestic logo threadwatch logo seochat tools logo