相关疑难解决方法(0)

为什么GCC在实现整数除法时使用乘以奇数的乘法?

我一直在阅读divmul组装操作,我决定通过在C中编写一个简单的程序来实现它们:

文件分割

#include <stdlib.h>
#include <stdio.h>

int main()
{
    size_t i = 9;
    size_t j = i / 5;
    printf("%zu\n",j);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后生成汇编语言代码:

gcc -S division.c -O0 -masm=intel
Run Code Online (Sandbox Code Playgroud)

但是看生成的division.s文件,它不包含任何div操作!相反,它通过位移和魔术数字来做某种黑魔法.这是一个计算代码片段i/5:

mov     rax, QWORD PTR [rbp-16]   ; Move i (=9) to RAX
movabs  rdx, -3689348814741910323 ; Move some magic number to RDX (?)
mul     rdx                       ; Multiply 9 by magic number
mov     rax, rdx                  ; Take only the upper 64 bits of the …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc x86-64 integer-division

206
推荐指数
4
解决办法
1万
查看次数

132
推荐指数
4
解决办法
10万
查看次数

使用位移除以10?

是否有可能通过使用纯位加法,减法除以10的无符号整数,也许繁衍?使用资源非常有限且速度慢的处理器.

math bit low-level integer-division micro-optimization

41
推荐指数
4
解决办法
5万
查看次数

如何在装配NASM中打印数字?

假设我在寄存器中有一个整数,我该如何打印?你能展示一个简单的示例代码吗?

我已经知道如何打印一个字符串,如"你好,世界".

我正在Linux上开发.

linux x86 assembly nasm

15
推荐指数
3
解决办法
3万
查看次数

在x86程序集中将整数打印到控制台

当我在16位汇编中添加两个值时,将结果打印到控制台的最佳方法是什么?

目前我有这个代码:

;;---CODE START---;;
mov ax, 1   ;put 1 into ax
add ax, 2   ; add 2 to ax current value
mov ah,2  ; 2 is the function number of output char in the DOS Services.
mov dl, ax ; DL takes the value.
int 21h    ; calls DOS Services

mov ah,4Ch   ; 4Ch is the function number for exit program in DOS Services.
int 21h      ; function 4Ch doesn't care about anything in the registers.
;;---CODE END---;;
Run Code Online (Sandbox Code Playgroud)

我认为dl值应该是ASCII码,但我不确定如何在添加到ASCII后转换ax值.

assembly dos 16-bit

7
推荐指数
2
解决办法
2万
查看次数

在Linux上输出程序集中的整数

这需要在纯汇编中完成(即没有库或调用C).

我理解问题的本质:需要将整数除以10,将一位数的余数转换为ASCII,然后输出,然后用商重复该过程.

但由于某种原因,它只是不起作用.我在x86上使用NASM.

这是我现在所拥有的(不输出任何内容,但也不会抛出任何汇编错误):

; integer to output is stored in eax
mov ecx, 10   ; for base 10

loop:
div ecx  ;EAX contains the quotient, EDX the remainder

; Do something to EDX to convert it to ASCII, not sure if this is correct
add edx, '0'

push eax    ;We'll be playing with EAX to output EDX, save EAX to the stack

mov eax, 4              ; sys_write
mov ebx, 1              ; to STDOUT
mov ecx, edx
mov edx, 1 …
Run Code Online (Sandbox Code Playgroud)

x86 assembly nasm

7
推荐指数
1
解决办法
3125
查看次数

NASM Linux程序集打印整数

我试图在linux上的nasm程序集中打印单个数字整数.我目前编写的内容很好,但没有任何内容写入屏幕.任何人都可以向我解释我在这里做错了什么吗?

section .text
    global _start

_start:
    mov ecx, 1          ; stores 1 in rcx
    add edx, ecx        ; stores ecx in edx
    add edx, 30h        ; gets the ascii value in edx
    mov ecx, edx        ; ascii value is now in ecx
    jmp write           ; jumps to write


write:
    mov eax, ecx        ; moves ecx to eax for writing
    mov eax, 4          ; sys call for write
    mov ebx, 1          ; stdout

    int 80h             ; call kernel
    mov eax,1           ; …
Run Code Online (Sandbox Code Playgroud)

linux assembly nasm

6
推荐指数
2
解决办法
8807
查看次数

Linux x86 NASM - 子程序:从EAX打印双字

所以我正在学习使用NASM语法的x86 Linux程序集(哦,上帝,不是这个,你们都在考虑).我正在尝试创建一个子程序,只需将EAX中的值打印到stdout即可.代码运行并退出而没有错误,但没有打印.我无法弄清楚为什么.首先,这是我正在处理的文件:

segment .bss
    to_print:   resd 1

segment .text
    global print_eax_val

print_eax_val:                  ;       (top)
    push    dword ebx           ;Stack:  edx
    push    dword ecx           ;        ecx
    push    dword edx           ;        ebx
                                ;       (bot)

    mov     ecx,eax             ;ecx = eax

    mov     [to_print],ecx      ;to_print = ecx

    mov     eax, 4              ;sys_write
    mov     ebx, 1              ;to stdout
    add     ecx, 47             ;add 47 for ASCII numbers
    mov     edx, 2              ;double word = 2 bytes
    int     0x80

    mov     eax, [to_print]     ;eax = original val
    pop     edx                 ;pop …
Run Code Online (Sandbox Code Playgroud)

linux x86 assembly nasm

6
推荐指数
1
解决办法
3664
查看次数

如何在emu 8086中用汇编语言打印0到100?

在这里,我尝试了一些方法来打印 10 到 0 的十进制数字emu8086

     .MODEL SMALL
     .STACK 100H
     .DATA
        NUM DB 58D

     .CODE
     MAIN PROC
          MOV AX,@DATA
          MOV DS,AX


     START:
         CMP NUM,48D 
         JGE PRINT
         JMP END_


     PRINT:
         MOV AH,2
         MOV DL,NUM
         INT 21H
         DEC NUM
         JMP START

     END_:
         MOV AH,4CH
         MAIN ENDP
     END MAIN
Run Code Online (Sandbox Code Playgroud)

它在打印 9 到 0 时工作得很好,但它不是打印 10 而是打印asciivalue 的字符10d。我是 .so 的新手,assembly language如何打印 0 到 100 个十进制数字?

assembly emu8086

6
推荐指数
1
解决办法
3万
查看次数

如何在没有系统调用的情况下在x86-64程序集(NASM)中将字符串打印到终端?

我是装配新手,并希望首先尝试直观地了解如何将字符串打印到终端上,而无需通过操作系统抽象(Linux或OSX).

tl; dr如何在OSX上使用NASM在x86-64程序集中写入stdout(打印到终端),尽可能最低级别(即没有系统调用)?BareMetal OS如何做到这一点?

大多数示例显示类似这样:

global start

section .text
start:
  mov rax, 1
  mov rdi, 1
  mov rsi, message
  mov rdx, 13
  syscall

  mov eax, 60
  xor rdi, rdi
  syscall

message:
  db "Hello world", 10
Run Code Online (Sandbox Code Playgroud)

在那里,他们syscall用来打印依赖于操作系统的字符串.我不是在寻找那个,而是为了如何在最低级别直接将字符串写入stdout.

有这个exokernel项目,BareMetal OS,我认为这样做.虽然因为我不熟悉集会,但我还不知道他们是如何做到这一点的.从它看来,两个重要的文件是:

打印的相关代码似乎是这个(从这两个文件中提取):

;
; Display text in terminal.
;
;  IN:  RSI = message location (zero-terminated string)
; OUT:  All registers preserved
;

os_output:
  push rcx

  call os_string_length
  call os_output_chars …
Run Code Online (Sandbox Code Playgroud)

assembly nasm

4
推荐指数
1
解决办法
2万
查看次数

标签 统计

assembly ×9

nasm ×5

linux ×4

x86 ×3

integer-division ×2

x86-64 ×2

16-bit ×1

abi ×1

bit ×1

c ×1

dos ×1

emu8086 ×1

gcc ×1

low-level ×1

math ×1

micro-optimization ×1

unix ×1