- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我阅读了关于 nasm 的教程,有一个代码示例显示了整个 ascii 字符集。除了为什么我们要推送 ecx 和弹出 ecx 之外,我几乎了解所有内容,因为我看不到它与其余代码的关系。 Ecx 的值为 256,因为我们想要所有字符,但不知道在哪里以及如何使用它。当我们 push 和 pop ecx 时到底发生了什么?为什么我们要把achar的地址移到dx?我没有看到我们使用 dx 做任何事情。我知道我们需要增加 achar 的地址,但我很困惑增量与 ecx 和 dx 的关系。我会很感激一些见解。
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
call display
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
display:
mov ecx, 256
next:
push ecx
mov eax, 4
mov ebx, 1
mov ecx, achar
mov edx, 1
int 80h
pop ecx
mov dx, [achar]
cmp byte [achar], 0dh
inc byte [achar]
loop next
ret
section .data
achar db '0'
最佳答案
I understand pretty much everything
why are we pushing ecx and popping ecx as I dont see how it relates to the rest of the code. Ecx has the value of 256 since we want all chars but no idea where and hows its used.
LOOP
指令使用(这不是一个好主意:
Why is the loop instruction slow? ),它将递减
ecx
,并在 value 大于零时跳转,即它是一个倒计时循环机制。
int 0x80
服务调用需要
ecx
作为内存地址值,因此计数器由
push
/
pop
保存/恢复。一种更高效的方法是将计数器值放入一些备用寄存器中,例如
esi
,然后执行
dec esi
jnz next
。更高效的方法是重新使用字符值本身,如果输出将从零值开始,而不是零数字,那么
inc byte [achar]
之后的零标志可用于检测循环条件。
achar db '0'
48
)开始,对我来说似乎很奇怪,我会从零开始。但这还有一个警告,linux 控制台 I/O 编码是由环境设置的,现在在任何常见的 linux 安装上都是 UTF8,因此有效的可打印单字节字符的值只有 32-126(与普通的 7位 ASCII 编码,使这部分示例工作良好),值 0-31 和 127 是不可打印的控制字符,也与常见的 7b ASCII 编码相同。值 128-255 表示 UTF8 编码的多字节字符(例如:
ř
是两个字节
0xC5 0x99
),作为单个字节,它们是无效的字节序列,因为缺少 UTF8“代码点”字节的剩余部分。
\r
和
\n
控制字符,它们对于 VGA 来说只是另一种字体字形,而不是换行符和换行符控制字符(该含义是由 BIOS/DOS 服务调用创建的,而不是输出
\n
字符将移动内部光标到下一行并丢弃输出中的字符)。
'0'
(
48
) 开始,直到值
126
它输出正确的可打印 ASCII 字符,在
126
之后它输出“某物”,并且由于这些字节有时会形成无效的 UTF8 编码,我会在技术上称之为具有未定义行为的“虚假”输出,对于不同的 linux 版本和控制台设置,您可能会得到不同的结果。
achar: db '0'
,当您不小心使用指令助记符作为标签时,如
loop:
或
dec: db 'd'
,这将节省您的时间。
mov dx, [achar]
dx
不再使用,因此这是无用的指令。
cmp byte [achar], 0dh
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
call display
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
; displays all valid printable ASCII characters (32-126), and new-line after.
display:
mov byte [achar], ' ' ; first valid printable ASCII
next:
mov eax, 4
mov ebx, 1
mov ecx, achar
mov edx, 1
int 0x80
inc byte [achar]
cmp byte [achar], 126
jbe next ; repeat until all chars are printed
; that will output all 32..126 printable ASCII characters
; display one more character, new line (reuse of registers)
mov byte [achar], `\n` ; NASM uses backticks for C-like meta chars
mov eax, 4 ; ebx, ecx and edx are already set from loop above
int 0x80
ret
section .bss
achar: resb 1 ; reserve one byte for character output
section .text
global _start ;makes symbol "_start" global (visible for linker)
_start: ;linker's default entry point
call display
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
; displays all valid printable ASCII characters (32-126), and new-line after.
display:
; prepare in memory string with all ASCII chars and new-line
mov al,' ' ; first valid printable ASCII
mov edi, allAsciiChars
mov ecx, edi ; this address will be used also for "write" int 0x80
nextChar:
mov [edi], al
inc edi
inc al
cmp al, 126
jbe nextChar
; add one more new line at end
mov byte [edi], `\n`
; display the prepared "string" in one "write" call
mov eax, 4 ; sys_write, ecx is already set
mov ebx, 1 ; file descriptor STDOUT
lea edx, [edi+1]; edx = edi+1 (memory address beyond last char)
sub edx, ecx ; edx = length of generated string
int 0x80
ret
section .bss
allAsciiChars: resb 126-' '+1+1 ; reserve space for ASCII characters and \n
nasm -f elf32 -F dwarf -g test.asm -l test.lst -w+all
ld -m elf_i386 -o test test.o
$ ./test
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
关于assembly - 在 linux 控制台中显示所有 ascii 字符(NASM 程序集),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48046707/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求提供代码的问题必须表现出对所解决问题的最低限度理解。包括尝试过的解决方案、为什么它们不起作用,以及预
为什么在 C# 中添加两个 char 结果是 int 类型? 例如,当我这样做时: var pr = 'R' + 'G' + 'B' + 'Y' + 'P'; pr 变量变为 int 类型。我希望它是
下面的代码可以编译,但 char 类型的行为与 int 类型的行为不同。 特别是 cout ::ikIsX >() ::ikIsX >() ::ikIsX >() using names
我正在寻找一个正则表达式,它可以匹配长度为 1 个或多个字符但不匹配 500 的内容。这将在 Rails 路由文件中使用,特别是用于处理异常。 路线.rb match '/500', to: 'err
对于 C 编程作业,我正在尝试编写几个头文件来检查所谓的“X 编程语言”的语法。我最近才开始,正在编写第一个头文件。这是我编写的代码: #ifndef _DeclarationsChecker_h_
为什么扩展的 ascii 字符(â、é 等)被替换为 字符? 我附上了一张图片...但我正在使用 PHP 从 MySQL 中提取数据,其中一些位置有扩展字符...我使用的是 Arial 字体。 您可以
我有一个与 R 中的断线相关的简单问题。 我正在尝试粘贴,但在获取(字符/数字)之间的断线时遇到问题。请注意,这些值包含在向量中(V1=81,V2=55,V3=25)我已经尝试过这段代码: cat(p
如何将 ANSI 字符 (char) 转换为 Unicode 字符 (wchar_t),反之亦然? 是否有用于此目的的任何跨平台源代码? 最佳答案 是的,在 中你有mbstowcs()和 wcsto
函数 fromCharCode 不适用于国际 ANSI 字符。例如,对于 ID 为 192 到 223 的俄语 ANSI (cp-1251) 字符,它返回特殊字符。如何解决这个问题? 我认为,需要将A
如果不喜欢,我想隐藏 id,但不起作用 SELECT * FROM character, character_actor WHERE character.id NOT LIKE character_a
现在这个程序成功地反转了键盘输入的单词。但是我想在我反转它之前“保存”指针中的单词,所以我可以比较两者,反转的和“原始的”,并检查它们是否是回文。我还没有太多经验,可能会出现比我知道的更多的错误,但我
Memcpy 和 memcmp 函数可以接受指针变量吗? char *p; char* q; memcpy(p,q,10); //will this work? memcmp(p,q,10); //w
恐怕我对一个相当过饱和的主题的细节有疑问,我搜索了很多,但找不到一个明确的答案来解决这个特定的明显-imho-重要的问题: 使用UTF-8将byte[]转换为String时,每个字节(8bit)都变成
我有一个奇怪的问题。我需要从 stat 命令打印输出字符串。 我已经编写了获取一些信息的代码。 import glob import os for file in glob.glob('system1
我正在使用 Java 并具有其值如下所示的字符串, String data = "vale-cx"; data = data.replaceAll("\\-", "\\-\\"); 我正在替换其中的“
String urlParameters = "login=test&password=te&ff"; 我有一个String urlParams,& - 是密码的一部分,如何使其转义,从而不被识别为分
大家好,我只想从此字符串中提取第一个字母: String str = "使 徒 行 傳 16:31 ERV-ZH"; 我只想获取这些字符: 使 徒 行 傳 并且不包括 ERV-ZH 仅数
这个问题已经有答案了: Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized point
所以, 我有一个字符**;它本质上是一个句子,带有指向该句子中每个单词的指针;即 'h''i''\0''w''o''r''l''d''\0''y''a''y''!''\0' 在这种情况下,我希望使用可
这个问题在这里已经有了答案: Using quotation marks inside quotation marks (12 个答案) 关闭 7 年前。 如何打印 " 字符? 我知道打印 % 符号
我是一名优秀的程序员,十分优秀!