windows,assembly,windows-8.1,nasm
I'll start with returning. main.asm [section] .text global _main _main: mov eax, 6 ret ; returns eax (exits) All this program does is return 6. Assemble and link like so: c:\Users\James\Desktop>nasm -fwin32 main.asm c:\Users\James\Desktop>ld -e _main main.obj -o main.exe c:\Users\James\Desktop>main.exe c:\Users\James\Desktop>echo %errorlevel% 6 Using a stack frame. main.asm [section] .text...
Use RESB and friends. See the nasm manual: 3.2.2 RESB and Friends: Declaring Uninitialized Data RESB, RESW, RESD, RESQ, REST, RESO, RESY and RESZ are designed to be used in the BSS section of a module: they declare uninitialized storage space. Each takes a single operand, which is the number...
There is no mov which takes 2 memory operands. See the instruction set reference. You can go through a byte-sized register, for example: mov dl, [rax] mov [rbx], dl Also note that the calling convention mandates some registers need to be preserved, including rbx. You could use rcx instead, or...
assembly,nasm,calling-convention
first Fragment is fastcall calling convention because the procedure has used the registers(EAX,EDX) without assigning values to it - which means the caller used the registers for passing the arguments - like in line mov [ ebp-0x4 ] , eax second Fragment is stdcall calling convention because the procedure cleaned...
It's not strictly required to keep the stack aligned, but that depends on what you are actually doing. If you have it just in your code it might be ok. If you call operating system functions it might have side effects. For example, I once got a strange error in...
For historical reasons. The x86 family started as a 16-bit architecture (8086). That was the time when the instruction set was defined, and all further processors have to be backward-compatible. The 80386 was the first 32-bit processor in the x86 series. BTW I am writing an assembler tutorial and I...
Since you haven't yet accepted an answer (<hint><hint>), let me add a third thought: 1) Instead of having 3 asm statements, do it in 1: asm(".intel_syntax prefix\n\t" "add %0, 1 \n\t" ".att_syntax prefix" : "=r" (dst) : "r" (src)); 2) Change your compile options to include -masm=intel and omit the...
c++,assembly,nasm,argument-passing
You have to preserve value of ebx in your asm functions (see http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl). Violating the calling convention may result in various range of errors, from subtle to crashes. Use ecx instead of ebx, or try div dword ptr [ebp+12]....
For this C-code with gcc-vector extensions, typedef float v4sf __attribute__((vector_size(16))); v4sf foo(float const *restrict a, float const *restrict b) { float const *restrict aa = __builtin_assume_aligned(a, 16); float const *restrict ba = __builtin_assume_aligned(b, 16); v4sf av = *(v4sf*)aa; v4sf bv = *(v4sf*)ba; v4sf sv = av+bv; float temp = sv[0]+sv[1]+sv[2];...
FIST does not pop the value from the floating point stack -- it leaves it there. It just so happens that the normal x86 calling conventions for returning a float value uses the floating point stack -- a function returning float returns with just that single value on the stack....
The easiest way would be to simply set the bit to what you want using AND or OR operations. If you want the high bit set to 1, use input OR 1000000. If you want it set to 0, use input AND 01111111. The remaining bits will be unchanged....
You can just load a byte into a 32 bit register using the zero-extend move instruction, and use it to add it to EBX: movzx eax,byte ptr [ebp-10+ecx] add ebx,eax Or, if you want to perform an 8-bit addition and don't care about the rest of bits of EBX, just...
You are probably probing pages that are reserved for stack. That may cause new stack pages to be allocated and eventually result in stack overflow. From Microsoft Support: In the Microsoft Windows NT operating system, stack overflow is detected by hardware and software working together, using the page protection mechanisms....
The DEFINE_ARGS macro defines a number single line macros the are meant to be used to refer to the arguments of the function that the cglobal macro introduces. So for example, if foo is given as the name of the first argument then DEFINE_ARGS creates the following defines: %xdefine fooq...
Your syntax is incorrect. You forgot the dots at the beginning of each structure member. Also, the value after resd is the number of data items to "reserve" in the structure. It should be 1 in this case, not 0. ;; Declare a structure called "node". ;; Its size is...
linux,pointers,assembly,nasm,syscall
At rsp+8 you'll find the address of a string with the program path. The pointer to the first argument is at [rsp+16]. But for execve you need a pointer to an array of pointer to strings which begins with a pointer to a program path (you can (ab)use [rsp+8]). So...
NASM gives special treatment to symbols beginning with a period. A label beginning with a single period is treated as a local label NASM does have a global directive, but it's written without an initial period. So perhaps you meant to write global _put_in_mem...
I guess you are using some code of Paul Carters tutorial. If this is the case you need to download asm_io.inc from http://www.drpaulcarter.com/pcasm/#exampleCode
The immediate problem is that your prints destroys bx (because it sets bl and bh) so your printmem loop which requires bx to be preserved blows up. However, it also destroys al so your input loop won't be storing the correct value in memory to start with, either. Furthermore, while...
linux,assembly,nasm,elf,syscall
You should have narrowed it down to a minimal example. See MCVE. You should comment your code if you want other people to help. You should learn to use the debugger and/or other tools. For point #1, you could have gone down to: section .text global _start ;must be...
Those are stdcall name decorations: Name-decoration convention An underscore (_) is prefixed to the name. The name is followed by the at sign (@) followed by the number of bytes (in decimal) in the argument list. Therefore, the function declared as int func( int a, double b ) is decorated...
In x86 assembly according to your assembler(e.g tasm, masm or nasm) you cannot compare immediates or variables with each other. You have to put one or both of them in a register. like this: mov ax, 5 cmp ax, 6 or mov ax, 5 mov bx, 6 cmp ax, bx...
Most likely, the problem is that the string doesn't contain a carriage return character (ASCII value 13). After each failed check (i.e. cmp al, 13), the ECX register is incremented and the jmp l1 instruction creates a loop. So you're going through the string looking for the value 13, but...
The problem is, you don't have debug info for the ptr type, so gdb treats it as integer. You can examine its real contents using: (gdb) x/a &ptr 0x600124 <ptr>: 0x7fffffffe950 (gdb) p/a $rsp $3 = 0x7fffffffe950 Of course I have a different value for rsp than you, but you...
Explanation You're using the wrong syscall numbers for x86-64 Linux. Thus your exit() call fails and instead dowork and callback end up in a mutual recursion, causing a loop. For the correct syscall numbers, see arch/x86/syscalls/syscall_64.tbl in the Linux source code: 1 common write sys_write 231 common exit_group sys_exit_group If...
The problem is that INT 16h AH=00h returns a ASCII character code in AL and an scan code in AH. The mov [qbuf], ax instruction stores both in the buffer, but INT 10h AH=0Eh only prints ASCII characters. It ends up interpreting the scan code you stored in the buffer...
try mov ah, 0Eh mov al, 07h int 10h http://en.wikipedia.org/wiki/INT_10H Teletype output AH=0Eh AL = Character...
While that works, there is a movzx instruction that moves with zero extension: movzx eax, [ebp - 5]. There is also movsx for sign extending but that's not useful for array indexing....
assembly,x86,nasm,equation,square
You've got a typo here: FLD dword [zmB] ; zmC - st0, zmB - st1, zmC - st2 That instruction should be FLD dword [zmC] By the way, you can replace these two lines: FLDZ ; 0 - st0, zmC - st1, zmB - st2, zmC - st3 FADD st0,st2...
You should change the order of the boot flag values: db 0x55 db 0xaa ...
Is there somewhere that has full coverage of what these instructions do in a 64-bit context? I can't seem to find a reference that actually tells me in plain English what is happening to the rdx register after the mul instruction Intel's manual puts it pretty clearly: MUL r/m64...
The program sums up the array correctly. The problem is with returning the result. [Answer corrected, thanks to Jester.] You pass the return value to sys_exit() (this is what mov eax, 1; int 0x80 does). sys_exit() leaves only the lower 8 bits of the return value (other bits are used...
Simply the value (number) 4 is loaded into eax, no magic there. The operating system will look at the value in eax to figure out what function you want. System call number is a code that identifies the various available kernel functions you can use.
c,assembly,floating-point,printf,nasm
Your dist is a single 32-bit float, but printf needs a double 64-bit float. You have to transform it: %macro print_dist2 1 section .data .str db %1,0 ; %1 is macro call first actual parameter section .text sub esp, 8 ; Space for a 64-bit double floating point number fld...
Here's the problem: push dword sum push dword fmtTest call printf printf, unlike scanf, takes its arguments (after the format) by value, while in your code sum is the address of the memory location. Just do: push [sum] push fmtTest call printf (incidentally, the xor eax,eax before the mov eax,[int1]...
The paging model on most systems will cause the pages comprising the sections of the binary not requiring some kind of dynamic linking to only be loaded when they are accessed - Windows is no exception. So, the .data section is memory-mapped as a binary file to your process memory...
The reason it crashes is probably that your main function doesn't have a ret instruction. Also be sure to set eax to 0 to signal success: xor eax, eax ; or `mov eax, 0` if you're more comfortable with that ret Additionally, global variables designate pointers, not values. mov eax,...
In your data section, set up what you want the prompt to be. In this example, I'll use ">>" to be the prompt: section .data prompt db ">>", 13, 10, '$' Then in your bss section, set up a string destination, and reserve a certain number of bytes for the...
Which assembler do you use? In nasm dw with a string will just pad the string to the two byte boundary. The difference between two and four bytes being read has nothing to do with db or dw but instead the use of ax (a two byte register) vs edx...
arrays,assembly,x86,stack,nasm
First read this for information about mul instruction. After you correct your mul instruction and use of result in your code everything works well. I correct your code as follow : section .data array: dd 1, 2, 3 arrayLen: dd 3 section .text global main main: push dword array push...
out has two forms, out <imm8>, al/ax/eax and out dx, al/ax/eax. Your instruction matches neither of these, so it is malformed. Change your code such that the value you want is in eax instead of ecx (which might be as easy as mov eax, ecx) and use the second form....
A really confusing thing about the stack is that it grows down. Compared to most people's mental image of a stack, the stack you work with in assembly is "upside down". The "bottom" of the stack has the highest memory address, and the "top" has the lowest. When you push...
The Intel manual lists the following variants of IMUL: F6 /5 IMUL r/m8* M Valid Valid AX? AL * r/m byte. F7 /5 IMUL r/m16 M Valid Valid DX:AX ? AX * r/m word. F7 /5 IMUL r/m32 M Valid Valid EDX:EAX ? EAX * r/m32. REX.W + F7 /5...
Generally, on x86, memory-to-memory operations are not supported. You need to first load one of the arguments into a register. Then you can compare that register content to another memory location. E.g: mov eax, DWORD [ebp - 25] cmp eax, [ebp + 12] ...
'mystring + 1' is the address of the second byte of the string. mov al, mystring + 1 stores (the least significant byte of) that address in al. To indicate that you don't want to store the address but the byte located at that address, write this: mov al, [mystring...
That's because there is no instruction that can move a literal value to the es register. There are different mov instructions for different combinations of sources and destinations. There is an instruction to move a literal value to registers, but it can only move it to certain registers, not all...
NASM is not case-sensitive (except for labels and variables) and will gladly accept mov, MOV or Mov as the same opcode.
You could use .data section for string values you want to use like \n or other strings you want to use and the use C function printf and scanf to deal with IO. Just add: extern printf, scanf at the beginning of your asm file, then: section .data input_n db...
You increment esi but you forget to store it into variable, so at the top of the loop the original value is read again. Move the line that stores esi after the label _middle. (And you don't need the line to retrieve variable into esi anymore.) As it seems you...
arrays,assembly,syntax,printf,nasm
The only thing that determines whether something is printed on a single line or multiple, is if you print a newline character (\n) or not. Here, when you say 10, that is the ASCII value for a Line Feed. If you change this: aoutput: db "%d", 10, 0 to this:...
windows,assembly,x86,nasm,memory-alignment
Yes. See the nasm manual: The defaults assumed by NASM if you do not specify the above qualifiers are: section .data progbits alloc noexec write align=4 section .bss nobits alloc noexec write align=4 Notice it says align=4. This is for ELF output. You have forgotten to specify what you use....
The reason might be that the write syscall returns an error code. It could be for many reasons, but maybe rdx is not all zeros, so you should xor %rdx, %rdx before loading 15 there (actually you should load 14 only, for "Hello, World!\n"). Anyway, the error from write would...
You are loading an integer into the floating point register and expecting it to treated as the same value in floating point. That's not how IEEE754 floating point works, the numbers use a different encoding scheme. The bit pattern formed by the integer 6580001 (0x00646701) is as shown in the...
BUFFLEN will be a compile-time symbol with the said value of 1024. It will only temporarily be stored by NASM in its internal tables while compiling. It will nowhere be stored in the executable. The section .BSS will not be stored in the executable as oppossed to the section .DATA...
As pointed out by Lurker and Michael in the comments: There is no Problem apart from the fact that my debugger attempts to interpret the "Loa" part of "LoadLibraryA" as an actual instruction because I've put the string literals in the .text (code) section. In the second example, this does...
String_01 db 'Hello, World', 0 String_02 dd String_01 Now String_02 is a label referring to a pointer to a string at String_01. The address of the first character of "Hello, World" can be found by coding mov esi,String_01 or mov esi,[String_02] ...
In addition to the issue that Michael mentioned, you appear to be using radius4 rather than radius3 FMUL st0,st0 ;; st0- radius^2 FMUL st0,st0 ;; st0- radius^3 // r2 * r2 = r4, not r3 ...
assembly,x86,nasm,bootloader,16-bit
Memory is addressed in bytes, not bits, so you need to add 1 byte, not 8 bits. As you have it, adding 8 to BX will address the memory 8 bytes above the H, which will be a 0 byte (since you specify times 510-($-$$) db 0 (iow, fill up...
You've got in R8 and thus in RSI an address not a character. So change the break condition cmp sil, 0 to cmp byte [rsi], 0.
assembly,operating-system,nasm,boot,bootloader
The problem isn't that you're setting ds before entering protected mode. The problem is that you're setting ds before executing the lgdt instruction. The lgdt instruction also accesses memory in the data segment, so ds needs to be a correct value when you execute it. When you changed ds, you...
Old MinGW versions had the problem that "ld" was not able to create non-PE files at all. Maybe current versions have the same problem. The work-around was creating a PE file with "ld" and then to transform the PE file to binary, HEX or S19 using "objcopy"....
You can use the FPU to convert a float into a writeable string. The following example takes PI (a number with quite a few digits) and separates the float into an integral and a fractional part, converts the integral part into a BCD number by using FBSTP, converts the BCD...
Well, the problem is that it is not just the mapping of hardware, as well as it is not just the bootloader in the computer. What you are really talking about is the writing of a driver. BIOS manages the simplest devices and uses the best available methods to achieve...
Here's an example from a course that I teach. This is a raw bootsector that you can compile directly as an object file and use as a bootable floppy or USB image in something like Qemu, VirtualBox, VMWare, Bochs or a real machine. This makes use of the real mode...
Thanks to rkhb for the answer to this one. push dword[junk+4] Is what should be here, rather than the minus....
You are talking about 2 different things here. Difference between db, dw, dd Jester gave you already the correct answer. Here are two examples from the NASM manual, which should help you to understand it. When you use dw, storage is created in steps of 1 word (2 bytes). Thus...
Here is a working example of your code. It works only, when the result is <10 aka when your result is only 1 digit long. section .bss buf: resb 1 res: resb 1 section .text global _start _start: ; you made the label _start global, ; but you forgot to...
assembly,shared-libraries,nasm,x86-64
Creating a shared library that calls function from another shared library might not be the best thing for a first assembly program ;) That said, here is what the nasm manual has to say about this: Referring to a procedure name using wrt ..plt causes the linker to build a...
It looks like stabs format doesn't work with GDB, try DWARF instead ( http://en.wikipedia.org/wiki/DWARF ) compile with nasm -f elf -g -F dwarf hello.asm then in gdb type start then si you will see sources with comments so on. as Koray Tugay said there is most probably a bug in...
assembly,x86,nasm,memory-address
Your address is an offset in a memory segment. Use instructions like the following if the segment is addressable through the DS segment register. mov [0200h], ax mov [0202h], ax Add a segment override prefix is the segment is addressable through ES. mov [es:0200h], ax mov [es:0202h], ax Depending on...
You're passing a value to sys_write instead of an address, that's not going to work. Write this instead : main: nop read: mov eax,3 ; Specify sys_read mov ebx,0 ; Specify standard input mov ecx,buff ; Where to read to... mov edx,bufflen ; How long to read int 80h ;...
It looks like you're trying to store the segment base of msg2 into es, and the keyword you're looking for is just SEG, not SEGMENT. Unfortunately, flat binary outputs do not support this, so you need a different solution. Instead, since you know msg2 is not going to be beyond...
Of course it is possible to relocate strings. First of all, your -Ttext 0x7C00 is correct. Do not change it. At the beginning of your bootloader you should zero the segment registers (%ds, %es, %fs, %gs and %ss): mov $0, %ax // xor %ax, %ax would be more space efficient...
PUSH imm8 doesn't actually push a byte onto the stack. It pushes at least a word, which will be sign-extended from the byte operand. Hence, with an operand of 0x80 you actually end up pushing 0xff80, 0xffffff80 or 0xffffffffffffff80, which most likely is what NASM is warning you about. This...
Two problems. One, the call strlen is allowed to clobber some registers which include rdi and you need that later. So, surround the call strlen with push rdi and pop rdi to save and restore it. Second, you do not initialize rdi in the print_newline block. You need to set...
I suspect that your issue is related to the newline implied to be in welcome db "Hello, this is the clock program", 10. I can't tell for sure because you didn't post that part of your code. I think that this causes an issue because the newline causes the terminal...
Actually, assembly doesn't work as simply as return true. Generally speaking, conditional execution is usually based on a status register. I will use Intel x86 architecture in this explanation. Note that other architectures are different, but the basic principle stays as far as I know. As mentioned before, the flow...
Surely nasm has given you the line number ... that should have pointed you at mul eax, 2. In turn, you should have then looked that instruction up in the reference manual and noticed that there is no mul instruction that accepts an immediate as an operand. There is such...
you're missing a mov ecx, esp after the last push for each of your argument pushes, as well as htons'ing the port number. A fixed version of you code should look like: BITS 32 section .text global _start _start: ; Create the socket file descriptor ; int socket(int domain, int...
windows,assembly,nasm,calling-convention
You can use any general-purpose register, and occasionally others, as the loop counter (just not the stack pointer of course ☺). Either you use one to loop manually, i.e. replace… loop label … with… dec ebp jnz label … which is faster anyway (because AMD (and later Intel, when they...
I think all 64-bit code on Mac is required to be rip relative. Absolute addresses are not supported. in this type of addressing you address your symbol relative to rip. NASM documentation says: default abs mov eax,[foo] ; 32−bit absolute disp, sign−extended mov eax,[a32 foo] ; 32−bit absolute disp, zero−extended...
What's with the "return;" line? That's not valid x86 and might be confusing the assembler into thinking you're trying to put a label there.
The string is defined as 13 bytes, but it is explicitly "null" terminated - a zero byte at the end serving as a marker to indicate the end of the string, see here. This is how you defined it array2: db "Hello, world!", 0 ; second array test for if...
mov ebp, 3 ;ebp = 3(constant) mov eax, edx ;eax = edx(sum from previous calculation) mov ecx,3 ;load upper half of dividend with zero div ecx ;divide double register ecx eax by 3 It seems like your doing the division the wrong way! The code does not what the comments...
If you declare the return type func as float the result will be returned in the FPU (ST0). For returning a value in EAX you have to declare it as an integer type. For printf you have to fake a float. Example: caller.c: #include <stdio.h> #include <stdint.h> extern float asmfunc1(float);...
arrays,assembly,printf,character,nasm
Changed code under .loopa label to make it print the character the index is corresponding to: .loopa: mov eax, 0 cmp [ebx+esi], eax je .skip mov eax, esi push ebx push ecx mov ebx, 4 cdq div ebx push eax push dword acoutput call printf add esp, 8 pop ecx...
Your first instruction is the problem: cmp rdi, 0. You're comparing the string pointer, passed to my_puts, to the value 0 to determine if you should print "(null)" rather than comparing the first byte of the string to 0. I'm supposing if you pass a 0 pointer, that would be...
Using brackets and not using brackets are basically two different things: A bracket means that the value in the memory at the given address is meant. An expression without a bracket means that the address (or value) itself is meant. Examples: mov ecx, 1234 Means: Write the value 1234 to...
The following appears to work fine for me: NAME = libfts.a SRC_ASM = file1.s \ file2.s \ file3.s \ OBJ_ASM = $(SRC_ASM:.s=.o) FLAGS = -Wall -Werror -Wextra NASM = nasm AR = ar RANLIB = ranlib ASM_FLAGS = -f macho64 all : $(NAME) $(NAME): $(OBJ_ASM) $(AR) rc $(NAME) $(OBJ_ASM) $(RANLIB)...